This commit is contained in:
2026-03-12 20:50:31 +03:00
parent 5a188b80e3
commit 43366a5089
9 changed files with 90 additions and 49 deletions

View File

@@ -45,9 +45,8 @@ onMounted(() => console.log('CHAT LIST'))
<VListItem value="logout" title="Log Out" />
</VList>
</VMenu>
<VSheet class="w-full">
<VTextField prepend-inner-icon="mdi-magnify" placeholder="search chat" />
</VSheet>
<VTextField bg-color="white" prepend-inner-icon="mdi-magnify" placeholder="search chat" />
</VToolbar>
<VList v-model:selected="selected" mandatory lines="one">
<ChatListElement v-for="chat in chatsStore.chats" :key="chat.id" v-bind="{ chat }" />

View File

@@ -8,7 +8,6 @@ import SettingsList from '@/components/Settings/SettingsList.vue'
const menuStore = useMenuStore()
const component = computed(() => {
console.log(menuStore.selected)
switch (menuStore.selected) {
case 'chats':
return ChatsList

View File

@@ -2,10 +2,10 @@
import { computed } from 'vue'
const props = withDefaults(
defineProps<{ createdAt?: string; username?: string; my?: boolean; text?: string }>(),
defineProps<{ createdAt?: string; username?: string; onRightSide?: boolean; message?: string }>(),
{
my: false,
text: 'foobar',
message: 'foobar',
username: 'robot',
},
)
@@ -35,14 +35,14 @@ const avatarLetter = computed(() => {
<!-- </div>-->
<!-- </div>-->
<div class="flex gap-2 border" :class="{ 'flex-row-reverse': props.my }">
<div class="flex gap-2" :class="{ 'flex-row-reverse': props.onRightSide }">
<!-- <v-avatar size="36" color="deep-purple-lighten-4">-->
<!-- <span class="text-deep-purple-darken-2">{{ avatarLetter }}</span>-->
<!-- </v-avatar>-->
<!-- :class="props.my ? 'message-shaped-right' : 'message-shaped'"-->
<div class="pa-4" :class="props.my ? 'bg-blue-400' : 'bg-white'">
<span class="">{{ props.text }}</span>
<div class="pa-4" :class="props.onRightSide ? 'bg-blue-400' : 'bg-white'">
<span class="">{{ props.message }}</span>
<span class="">{{ createdAt }}</span>
</div>
</div>

View File

@@ -27,13 +27,18 @@ const isEmptyText = computed(() => {
</script>
<template>
<div class="d-flex ga-2 border pa-4">
<input v-model="text" placeholder="message" @keyup.enter="sendMessage" />
<button><span class="mdi mdi-emoticon-outline"></span></button>
<button><span class="mdi mdi-paperclip"></span></button>
<button :disabled="isEmptyText" @click="sendMessage">
<span class="mdi mdi-send"></span>
</button>
<div class="flex gap-2 pa-2 items-center">
<VTextField
prepend-inner-icon="mdi-emoticon-outline"
append-inner-icon="mdi-paperclip"
bg-color="white"
v-model="text"
placeholder="message"
density="default"
@keyup.enter="sendMessage"
/>
<VBtn :disabled="isEmptyText" icon="mdi-send" @click="sendMessage" color="primary" />
</div>
</template>

View File

@@ -1,9 +1,13 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import type { User } from '@/stores/users.ts'
const {user} = defineProps<{ user: User }>()
</script>
<template>
<VToolbar class="px-2">
<VAvatar text="A" color="primary" />
<VToolbarTitle text="Message title" />
<VToolbarTitle :text="user.name" />
</VToolbar>
</template>

View File

@@ -1,28 +1,37 @@
<script setup lang="ts">
import { computed, nextTick, useTemplateRef, watch } from 'vue'
import { computed, nextTick, ref, useTemplateRef, watch } from 'vue'
import { useScroll } from '@vueuse/core'
import type { User } from '@/stores/users.ts'
const area = useTemplateRef('messageArea')
const { y, arrivedState } = useScroll(area)
// const { y, arrivedState } = useScroll(area)
const messages = computed(() => {
// const messages = computed(() => {
// return [...messagesStore.messages]
// })
// async function scrollToBottom() {
// await nextTick()
// if (area.value) y.value = area.value?.scrollHeight
// }
const user = ref<User>({
id: 1,
name: 'test',
email: 'test@test.ru',
})
async function scrollToBottom() {
await nextTick()
if (area.value) y.value = area.value?.scrollHeight
}
const messages = ref([])
</script>
<template>
<div class="flex h-full flex-col overflow-hidden">
<div class="grow-0">
<slot name="toolbar" />
<slot name="toolbar" :user="user" />
</div>
<div class="px-8 gap-2 grow flex flex-col-reverse overflow-y-auto" ref="messageArea">
<slot />
<slot :messages="messages" />
</div>
<div class="grow-0">
<slot name="input" />

View File

@@ -0,0 +1,35 @@
<script setup lang="ts">
import MessageData from '@/components/Messages/MessageData.vue'
import type { Message } from '@/stores/messages.ts'
const { messages } = defineProps<{ messages: Message[] }>()
</script>
<template>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData on-right-side>Hello world</MessageData>
<MessageData on-right-side>Hello world</MessageData>
<MessageData on-right-side>Hello world</MessageData>
<MessageData on-right-side>Hello world</MessageData>
<MessageData on-right-side>Hello world</MessageData>
<MessageData on-right-side>Hello world</MessageData>
<MessageData on-right-side>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
<MessageData>Hello world</MessageData>
</template>
<style scoped></style>

View File

@@ -3,34 +3,20 @@ import { useAuthStore } from '@/stores/auth.ts'
import MessagesForm from '@/components/Messages/MessagesForm.vue'
import MessageToolbar from '@/components/Messages/MessageToolbar.vue'
import MessageInput from '@/components/Messages/MessageInput.vue'
import MessageData from '@/components/Messages/MessageData.vue'
import { ref } from 'vue'
import type { Message } from '@/stores/messages.ts'
import MessagesList from '@/components/Messages/MessagesList.vue'
const authStore = useAuthStore()
// watch(messages, async () => {
// await scrollToBottom()
// })
const messages = ref<Message[]>([])
</script>
<template>
<div class="h-full bg-gray-300">
<div class="h-full bg-gray-100">
<div class="flex flex-col h-full">
<MessagesForm>
<template #toolbar>
<MessageToolbar />
<template #toolbar="{ user }">
<MessageToolbar :user />
</template>
<template #default>
<MessageData
v-for="message in messages"
:key="message.id"
:text="message.message"
:my="authStore.me?.id === message.userId"
:created-at="message.createdAt"
/>
<template #default="{ messages }">
<MessagesList :messages />
</template>
<template #input>
<MessageInput />

View File

@@ -58,16 +58,18 @@ export const useSocketsStore = defineStore('sockets', () => {
worker.value.port.onmessage = (event) => {
const { type, data, connected, message } = event.data
console.log('Received message', data)
switch (type) {
case SocketDataRes.USERS:
console.log('Received from back: USERS', data)
usersStore.users = data
break
case SocketDataRes.USER:
console.log('Received from back: USER', data)
authStore.me = data
break
case SocketDataRes.CHATS:
console.log('Received from back: CHATS', data)
if (Array.isArray(data)) {
chatsStore.chats = data
} else {
@@ -80,12 +82,14 @@ export const useSocketsStore = defineStore('sockets', () => {
break
case SocketDataRes.MESSAGES:
console.log('Received from back: MESSAGES', data)
messagesStore.messages = data
// if (options.onMessage) {
// options.onMessage(data)
// }
break
case SocketDataRes.MESSAGE:
console.log('Received from back: MESSAGE', data)
messagesStore.messages.unshift(data)
break
case SocketDataRes.STATUS: