Chat logics
This commit is contained in:
parent
e7def2ecf1
commit
86cebf07e2
@ -1,5 +1,82 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="chat-wrapper w-full h-full flex justify-start items-center">
|
<div class="chat-wrapper w-full h-full flex flex-col justify-end">
|
||||||
<input class="bg-[calc(100%_-_25px)_center] max-w-[750px] w-full h-12 rounded-lg text-xl px-6 py-0 bg-white/85 border-2 border-solid border-white text-gray-200 bg-[url('/assets/icons/submit-icon.svg')] bg-no-repeat bg-30px" placeholder="Type something..." />
|
<div ref="chatWindow" class="chat-window w-full max-w-[750px] min-h-36 mb-5 overflow-y-auto bg-gray-300/80 rounded-lg border-2 border-solid border-cyan-200 p-4">
|
||||||
|
<div v-for="message in chats" class="flex-col py-2 items-center">
|
||||||
|
<span class="text-ellipsis overflow-hidden whitespace-nowrap text-sm text-gray-50">{{ message.character.name }}</span>
|
||||||
|
<p class="text-sm m-0">{{ message.message }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="w-full flex mb-5">
|
||||||
|
<input
|
||||||
|
class="bg-[calc(100%_-_25px)_center] max-w-[750px] w-full h-12 rounded-lg text-xl px-4 py-0 bg-gray-300/80 border-2 border-solid border-cyan-200 text-gray-50 bg-[url('/assets/icons/submit-icon.svg')] bg-no-repeat bg-30px focus:outline-none focus:ring-0 focus:border-cyan-800"
|
||||||
|
placeholder="Type something..."
|
||||||
|
v-model="message"
|
||||||
|
@keypress="handleKeyPress"
|
||||||
|
@submit="handleSubmit"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onBeforeUnmount, onMounted, ref, nextTick } from 'vue'
|
||||||
|
import { useGameStore } from '@/stores/game'
|
||||||
|
import { useNotificationStore } from '@/stores/notifications'
|
||||||
|
import type { Character } from '@/types'
|
||||||
|
|
||||||
|
const gameStore = useGameStore()
|
||||||
|
const notifications = useNotificationStore()
|
||||||
|
|
||||||
|
const message = ref('')
|
||||||
|
const chats = ref([] as ChatMessage[])
|
||||||
|
const chatWindow = ref<HTMLElement | null>(null)
|
||||||
|
|
||||||
|
const sendMessage = () => {
|
||||||
|
if (!message.value.trim()) return
|
||||||
|
gameStore.connection?.emit('chat:send_message', { message: message.value }, (response: boolean) => {
|
||||||
|
if (!response) {
|
||||||
|
notifications.addNotification({ message: 'Failed to send message' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
message.value = ''
|
||||||
|
})
|
||||||
|
message.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = (event: Event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
sendMessage()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleKeyPress = (event: KeyboardEvent) => {
|
||||||
|
if (event.key === 'Enter' && !event.shiftKey) {
|
||||||
|
event.preventDefault()
|
||||||
|
sendMessage()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const scrollToBottom = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
if (chatWindow.value) {
|
||||||
|
chatWindow.value.scrollTop = chatWindow.value.scrollHeight
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChatMessage = {
|
||||||
|
character: Character
|
||||||
|
message: string
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
gameStore.connection?.on('chat:message', (data: ChatMessage) => {
|
||||||
|
chats.value.push(data)
|
||||||
|
scrollToBottom()
|
||||||
|
})
|
||||||
|
scrollToBottom()
|
||||||
|
})
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
gameStore.connection?.off('chat:message')
|
||||||
|
})
|
||||||
|
</script>
|
Loading…
x
Reference in New Issue
Block a user