chore: 스팟 채팅 잔여 코드 제거 (미사용 ChatDialog·createSpotChat)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,147 +0,0 @@
|
||||
<template>
|
||||
<q-dialog :model-value="modelValue" @update:model-value="$emit('update:modelValue', $event)" maximized>
|
||||
<q-card class="column no-wrap">
|
||||
<q-toolbar class="bg-primary text-white">
|
||||
<q-icon name="chat" class="q-mr-sm" />
|
||||
<q-toolbar-title>{{ spotName }} 채팅</q-toolbar-title>
|
||||
<q-chip dense :color="connected ? 'positive' : 'grey-5'" text-color="white">
|
||||
{{ connected ? '실시간' : '연결 중…' }}
|
||||
</q-chip>
|
||||
<q-btn flat round dense icon="close" @click="close" />
|
||||
</q-toolbar>
|
||||
|
||||
<!-- 메시지 목록 -->
|
||||
<q-scroll-area ref="scrollArea" class="col q-pa-md" style="background: #f4faff">
|
||||
<div v-if="!messages.length" class="text-center text-grey-5 q-mt-lg">
|
||||
첫 메시지를 남겨보세요. 이 스팟에 체크인한 이웃들과 대화해요.
|
||||
</div>
|
||||
<div
|
||||
v-for="m in messages"
|
||||
:key="m.id"
|
||||
class="q-mb-sm row"
|
||||
:class="isMine(m) ? 'justify-end' : 'justify-start'"
|
||||
>
|
||||
<div :class="isMine(m) ? 'msg mine' : 'msg'">
|
||||
<div v-if="!isMine(m)" class="text-caption text-weight-medium text-accent">
|
||||
{{ m.senderNickname }}
|
||||
</div>
|
||||
<div>{{ m.content }}</div>
|
||||
<div class="text-caption text-grey-6 text-right">{{ time(m.createdAt) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-scroll-area>
|
||||
|
||||
<!-- 입력 -->
|
||||
<div class="row q-pa-sm q-gutter-sm bg-white items-center">
|
||||
<q-input
|
||||
v-model="draft"
|
||||
class="col"
|
||||
dense
|
||||
outlined
|
||||
placeholder="메시지 입력…"
|
||||
maxlength="1000"
|
||||
:disable="!connected"
|
||||
@keyup.enter="send"
|
||||
/>
|
||||
<q-btn round color="primary" icon="send" :disable="!connected || !draft.trim()" @click="send" />
|
||||
</div>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onBeforeUnmount, ref, watch } from 'vue'
|
||||
import { QScrollArea, useQuasar } from 'quasar'
|
||||
import { chatApi, type ChatMessage } from '@/api/chat'
|
||||
import { createSpotChat } from '@/lib/chatSocket'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
|
||||
const props = defineProps<{ modelValue: boolean; spotId: number; spotName: string }>()
|
||||
const emit = defineEmits<{ (e: 'update:modelValue', v: boolean): void }>()
|
||||
|
||||
const $q = useQuasar()
|
||||
const auth = useAuthStore()
|
||||
|
||||
const messages = ref<ChatMessage[]>([])
|
||||
const draft = ref('')
|
||||
const connected = ref(false)
|
||||
const scrollArea = ref<QScrollArea | null>(null)
|
||||
let chat: ReturnType<typeof createSpotChat> | null = null
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
async (open) => {
|
||||
if (open) await start()
|
||||
else stop()
|
||||
},
|
||||
)
|
||||
|
||||
onBeforeUnmount(stop)
|
||||
|
||||
async function start() {
|
||||
messages.value = []
|
||||
try {
|
||||
messages.value = await chatApi.history(props.spotId)
|
||||
scrollToBottom()
|
||||
} catch {
|
||||
// 히스토리 실패해도 실시간 연결은 시도
|
||||
}
|
||||
chat = createSpotChat(
|
||||
props.spotId,
|
||||
(m) => {
|
||||
messages.value.push(m)
|
||||
scrollToBottom()
|
||||
},
|
||||
(c) => (connected.value = c),
|
||||
)
|
||||
chat.activate()
|
||||
}
|
||||
|
||||
function stop() {
|
||||
chat?.deactivate()
|
||||
chat = null
|
||||
connected.value = false
|
||||
}
|
||||
|
||||
function send() {
|
||||
const text = draft.value.trim()
|
||||
if (!text || !chat) return
|
||||
chat.send(text)
|
||||
draft.value = ''
|
||||
}
|
||||
|
||||
function close() {
|
||||
emit('update:modelValue', false)
|
||||
}
|
||||
|
||||
function isMine(m: ChatMessage) {
|
||||
return m.senderId === auth.member?.id
|
||||
}
|
||||
|
||||
function time(iso: string) {
|
||||
const d = new Date(iso)
|
||||
return d.toLocaleTimeString('ko-KR', { hour: '2-digit', minute: '2-digit' })
|
||||
}
|
||||
|
||||
function scrollToBottom() {
|
||||
nextTick(() => {
|
||||
const el = scrollArea.value
|
||||
if (el) el.setScrollPercentage('vertical', 1, 150)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.msg {
|
||||
max-width: 76%;
|
||||
padding: 8px 12px;
|
||||
border-radius: 12px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #e3eef7;
|
||||
word-break: break-word;
|
||||
}
|
||||
.msg.mine {
|
||||
background: #d7ecfb;
|
||||
border-color: #cfe8fb;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user