wip
This commit is contained in:
@@ -45,9 +45,8 @@ onMounted(() => console.log('CHAT LIST'))
|
|||||||
<VListItem value="logout" title="Log Out" />
|
<VListItem value="logout" title="Log Out" />
|
||||||
</VList>
|
</VList>
|
||||||
</VMenu>
|
</VMenu>
|
||||||
<VSheet class="w-full">
|
|
||||||
<VTextField prepend-inner-icon="mdi-magnify" placeholder="search chat" />
|
<VTextField bg-color="white" prepend-inner-icon="mdi-magnify" placeholder="search chat" />
|
||||||
</VSheet>
|
|
||||||
</VToolbar>
|
</VToolbar>
|
||||||
<VList v-model:selected="selected" mandatory lines="one">
|
<VList v-model:selected="selected" mandatory lines="one">
|
||||||
<ChatListElement v-for="chat in chatsStore.chats" :key="chat.id" v-bind="{ chat }" />
|
<ChatListElement v-for="chat in chatsStore.chats" :key="chat.id" v-bind="{ chat }" />
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import SettingsList from '@/components/Settings/SettingsList.vue'
|
|||||||
const menuStore = useMenuStore()
|
const menuStore = useMenuStore()
|
||||||
|
|
||||||
const component = computed(() => {
|
const component = computed(() => {
|
||||||
console.log(menuStore.selected)
|
|
||||||
switch (menuStore.selected) {
|
switch (menuStore.selected) {
|
||||||
case 'chats':
|
case 'chats':
|
||||||
return ChatsList
|
return ChatsList
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{ createdAt?: string; username?: string; my?: boolean; text?: string }>(),
|
defineProps<{ createdAt?: string; username?: string; onRightSide?: boolean; message?: string }>(),
|
||||||
{
|
{
|
||||||
my: false,
|
my: false,
|
||||||
text: 'foobar',
|
message: 'foobar',
|
||||||
username: 'robot',
|
username: 'robot',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -35,14 +35,14 @@ const avatarLetter = computed(() => {
|
|||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
<!-- </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">-->
|
<!-- <v-avatar size="36" color="deep-purple-lighten-4">-->
|
||||||
<!-- <span class="text-deep-purple-darken-2">{{ avatarLetter }}</span>-->
|
<!-- <span class="text-deep-purple-darken-2">{{ avatarLetter }}</span>-->
|
||||||
<!-- </v-avatar>-->
|
<!-- </v-avatar>-->
|
||||||
|
|
||||||
<!-- :class="props.my ? 'message-shaped-right' : 'message-shaped'"-->
|
<!-- :class="props.my ? 'message-shaped-right' : 'message-shaped'"-->
|
||||||
<div class="pa-4" :class="props.my ? 'bg-blue-400' : 'bg-white'">
|
<div class="pa-4" :class="props.onRightSide ? 'bg-blue-400' : 'bg-white'">
|
||||||
<span class="">{{ props.text }}</span>
|
<span class="">{{ props.message }}</span>
|
||||||
<span class="">{{ createdAt }}</span>
|
<span class="">{{ createdAt }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -27,13 +27,18 @@ const isEmptyText = computed(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="d-flex ga-2 border pa-4">
|
<div class="flex gap-2 pa-2 items-center">
|
||||||
<input v-model="text" placeholder="message" @keyup.enter="sendMessage" />
|
<VTextField
|
||||||
<button><span class="mdi mdi-emoticon-outline"></span></button>
|
prepend-inner-icon="mdi-emoticon-outline"
|
||||||
<button><span class="mdi mdi-paperclip"></span></button>
|
append-inner-icon="mdi-paperclip"
|
||||||
<button :disabled="isEmptyText" @click="sendMessage">
|
bg-color="white"
|
||||||
<span class="mdi mdi-send"></span>
|
v-model="text"
|
||||||
</button>
|
placeholder="message"
|
||||||
|
density="default"
|
||||||
|
@keyup.enter="sendMessage"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<VBtn :disabled="isEmptyText" icon="mdi-send" @click="sendMessage" color="primary" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
<template>
|
||||||
<VToolbar class="px-2">
|
<VToolbar class="px-2">
|
||||||
<VAvatar text="A" color="primary" />
|
<VAvatar text="A" color="primary" />
|
||||||
<VToolbarTitle text="Message title" />
|
<VToolbarTitle :text="user.name" />
|
||||||
</VToolbar>
|
</VToolbar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,37 @@
|
|||||||
<script setup lang="ts">
|
<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 { useScroll } from '@vueuse/core'
|
||||||
|
import type { User } from '@/stores/users.ts'
|
||||||
|
|
||||||
const area = useTemplateRef('messageArea')
|
const area = useTemplateRef('messageArea')
|
||||||
|
|
||||||
const { y, arrivedState } = useScroll(area)
|
// const { y, arrivedState } = useScroll(area)
|
||||||
|
|
||||||
const messages = computed(() => {
|
// const messages = computed(() => {
|
||||||
// return [...messagesStore.messages]
|
// 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() {
|
const messages = ref([])
|
||||||
await nextTick()
|
|
||||||
if (area.value) y.value = area.value?.scrollHeight
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex h-full flex-col overflow-hidden">
|
<div class="flex h-full flex-col overflow-hidden">
|
||||||
<div class="grow-0">
|
<div class="grow-0">
|
||||||
<slot name="toolbar" />
|
<slot name="toolbar" :user="user" />
|
||||||
</div>
|
</div>
|
||||||
<div class="px-8 gap-2 grow flex flex-col-reverse overflow-y-auto" ref="messageArea">
|
<div class="px-8 gap-2 grow flex flex-col-reverse overflow-y-auto" ref="messageArea">
|
||||||
<slot />
|
<slot :messages="messages" />
|
||||||
</div>
|
</div>
|
||||||
<div class="grow-0">
|
<div class="grow-0">
|
||||||
<slot name="input" />
|
<slot name="input" />
|
||||||
|
|||||||
35
src/components/Messages/MessagesList.vue
Normal file
35
src/components/Messages/MessagesList.vue
Normal 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>
|
||||||
@@ -3,34 +3,20 @@ import { useAuthStore } from '@/stores/auth.ts'
|
|||||||
import MessagesForm from '@/components/Messages/MessagesForm.vue'
|
import MessagesForm from '@/components/Messages/MessagesForm.vue'
|
||||||
import MessageToolbar from '@/components/Messages/MessageToolbar.vue'
|
import MessageToolbar from '@/components/Messages/MessageToolbar.vue'
|
||||||
import MessageInput from '@/components/Messages/MessageInput.vue'
|
import MessageInput from '@/components/Messages/MessageInput.vue'
|
||||||
import MessageData from '@/components/Messages/MessageData.vue'
|
import MessagesList from '@/components/Messages/MessagesList.vue'
|
||||||
import { ref } from 'vue'
|
|
||||||
import type { Message } from '@/stores/messages.ts'
|
|
||||||
|
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
|
|
||||||
// watch(messages, async () => {
|
|
||||||
// await scrollToBottom()
|
|
||||||
// })
|
|
||||||
|
|
||||||
const messages = ref<Message[]>([])
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="h-full bg-gray-300">
|
<div class="h-full bg-gray-100">
|
||||||
<div class="flex flex-col h-full">
|
<div class="flex flex-col h-full">
|
||||||
<MessagesForm>
|
<MessagesForm>
|
||||||
<template #toolbar>
|
<template #toolbar="{ user }">
|
||||||
<MessageToolbar />
|
<MessageToolbar :user />
|
||||||
</template>
|
</template>
|
||||||
<template #default>
|
<template #default="{ messages }">
|
||||||
<MessageData
|
<MessagesList :messages />
|
||||||
v-for="message in messages"
|
|
||||||
:key="message.id"
|
|
||||||
:text="message.message"
|
|
||||||
:my="authStore.me?.id === message.userId"
|
|
||||||
:created-at="message.createdAt"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<template #input>
|
<template #input>
|
||||||
<MessageInput />
|
<MessageInput />
|
||||||
|
|||||||
@@ -58,16 +58,18 @@ export const useSocketsStore = defineStore('sockets', () => {
|
|||||||
|
|
||||||
worker.value.port.onmessage = (event) => {
|
worker.value.port.onmessage = (event) => {
|
||||||
const { type, data, connected, message } = event.data
|
const { type, data, connected, message } = event.data
|
||||||
console.log('Received message', data)
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SocketDataRes.USERS:
|
case SocketDataRes.USERS:
|
||||||
|
console.log('Received from back: USERS', data)
|
||||||
usersStore.users = data
|
usersStore.users = data
|
||||||
break
|
break
|
||||||
case SocketDataRes.USER:
|
case SocketDataRes.USER:
|
||||||
|
console.log('Received from back: USER', data)
|
||||||
authStore.me = data
|
authStore.me = data
|
||||||
break
|
break
|
||||||
case SocketDataRes.CHATS:
|
case SocketDataRes.CHATS:
|
||||||
|
console.log('Received from back: CHATS', data)
|
||||||
if (Array.isArray(data)) {
|
if (Array.isArray(data)) {
|
||||||
chatsStore.chats = data
|
chatsStore.chats = data
|
||||||
} else {
|
} else {
|
||||||
@@ -80,12 +82,14 @@ export const useSocketsStore = defineStore('sockets', () => {
|
|||||||
|
|
||||||
break
|
break
|
||||||
case SocketDataRes.MESSAGES:
|
case SocketDataRes.MESSAGES:
|
||||||
|
console.log('Received from back: MESSAGES', data)
|
||||||
messagesStore.messages = data
|
messagesStore.messages = data
|
||||||
// if (options.onMessage) {
|
// if (options.onMessage) {
|
||||||
// options.onMessage(data)
|
// options.onMessage(data)
|
||||||
// }
|
// }
|
||||||
break
|
break
|
||||||
case SocketDataRes.MESSAGE:
|
case SocketDataRes.MESSAGE:
|
||||||
|
console.log('Received from back: MESSAGE', data)
|
||||||
messagesStore.messages.unshift(data)
|
messagesStore.messages.unshift(data)
|
||||||
break
|
break
|
||||||
case SocketDataRes.STATUS:
|
case SocketDataRes.STATUS:
|
||||||
|
|||||||
Reference in New Issue
Block a user