wip
This commit is contained in:
@@ -5,7 +5,12 @@ const menuStore = useMenuStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VBtn icon="mdi-arrow-left" size="small" @click="menuStore.selected = 'chats'" />
|
||||
<VBtn
|
||||
icon="mdi-arrow-left"
|
||||
color="default"
|
||||
size="small"
|
||||
@click="menuStore.selected = ['chats']"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { type Chat } from '@/stores/chats.ts'
|
||||
import { useAuthStore } from '@/stores/auth.ts'
|
||||
import { type Chat, useChatsStore } from '@/stores/chats.ts'
|
||||
import { computed } from 'vue'
|
||||
|
||||
interface Props {
|
||||
@@ -8,18 +7,10 @@ interface Props {
|
||||
}
|
||||
|
||||
const { chat } = defineProps<Props>()
|
||||
const authStore = useAuthStore()
|
||||
const chatsStore = useChatsStore()
|
||||
|
||||
const chatName = computed(() => {
|
||||
switch (chat.typeId) {
|
||||
case 1:
|
||||
const otherUsers = chat.users.filter((user) => user.id !== authStore.me?.id)
|
||||
return otherUsers[0]?.name ?? otherUsers[0]?.email ?? 'unknown'
|
||||
case 2:
|
||||
return chat.name
|
||||
default:
|
||||
return 'chat'
|
||||
}
|
||||
return chatsStore.getChatInfo(chat).name
|
||||
})
|
||||
|
||||
const lastMessage = computed(() => {
|
||||
|
||||
@@ -1,44 +1,34 @@
|
||||
<script setup lang="ts">
|
||||
import { useChatsStore } from '@/stores/chats.ts'
|
||||
import { SocketDataReq, useSocketsStore } from '@/stores/sockets.ts'
|
||||
import { onMounted, ref, watch, watchEffect } from 'vue'
|
||||
import { type SelectedMenu, useMenuStore } from '@/stores/menu.ts'
|
||||
import { watchEffect } from 'vue'
|
||||
import { useMenuStore } from '@/stores/menu.ts'
|
||||
import ChatListElement from '@/components/Chats/ChatListElement.vue'
|
||||
|
||||
const chatsStore = useChatsStore()
|
||||
const socketsStore = useSocketsStore()
|
||||
const menuStore = useMenuStore()
|
||||
const selected = ref<string[]>()
|
||||
const menu = ref<string[]>()
|
||||
|
||||
watchEffect(() => getMessages(chatsStore.selected))
|
||||
watch(selected, (val) => {
|
||||
if (val) chatsStore.selected = val[0]
|
||||
})
|
||||
|
||||
watch(menu, (val) => {
|
||||
if (val) menuStore.selected = val[0] as SelectedMenu
|
||||
})
|
||||
|
||||
function getMessages(chatId?: string) {
|
||||
if (!chatId) return
|
||||
socketsStore.send({
|
||||
type: SocketDataReq.GET_MESSAGES,
|
||||
data: { chatId: chatId },
|
||||
})
|
||||
function getMessages([selected]: string[]) {
|
||||
if (selected) {
|
||||
socketsStore.send({
|
||||
type: SocketDataReq.GET_MESSAGES,
|
||||
data: { chatId: selected },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => console.log('CHAT LIST'))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col h-full">
|
||||
<VToolbar class="px-2">
|
||||
<VToolbar theme="dark" class="px-2">
|
||||
<VMenu transition="slide-y-transition">
|
||||
<template v-slot:activator="{ props }">
|
||||
<VBtn size="small" icon="mdi-menu" class="mr-2" v-bind="props" />
|
||||
<VBtn size="small" icon="mdi-menu" class="mr-2" color="white" v-bind="props" />
|
||||
</template>
|
||||
<VList class="top-1" density="compact" slim v-model:selected="menu">
|
||||
<VList class="top-1" density="compact" slim v-model:selected="menuStore.selected">
|
||||
<VListItem value="users" title="Contacts" prepend-gap="8" prepend-icon="mdi-account" />
|
||||
<VListItem value="settings" title="Settings" prepend-gap="8" prepend-icon="mdi-cog" />
|
||||
<VDivider class="my-1" />
|
||||
@@ -46,10 +36,10 @@ onMounted(() => console.log('CHAT LIST'))
|
||||
</VList>
|
||||
</VMenu>
|
||||
|
||||
<VTextField bg-color="white" prepend-inner-icon="mdi-magnify" placeholder="search chat" />
|
||||
<VTextField bg-color="black" 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 }" />
|
||||
<VList theme="dark" v-model:selected="chatsStore.selected" mandatory lines="one">
|
||||
<ChatListElement v-for="chat in chatsStore.chats" :key="chat.id" :chat />
|
||||
</VList>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -8,7 +8,7 @@ import SettingsList from '@/components/Settings/SettingsList.vue'
|
||||
const menuStore = useMenuStore()
|
||||
|
||||
const component = computed(() => {
|
||||
switch (menuStore.selected) {
|
||||
switch (menuStore.selected[0]) {
|
||||
case 'chats':
|
||||
return ChatsList
|
||||
case 'users':
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
import type { User } from '@/stores/users.ts'
|
||||
interface Props {
|
||||
name: string
|
||||
image?: string
|
||||
}
|
||||
|
||||
const {user} = defineProps<{ user: User }>()
|
||||
const { name, image } = defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VToolbar class="px-2">
|
||||
<VToolbar theme="dark" class="px-2">
|
||||
<VAvatar text="A" color="primary" />
|
||||
<VToolbarTitle :text="user.name" />
|
||||
<VToolbarTitle :text="name" />
|
||||
</VToolbar>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -2,33 +2,27 @@
|
||||
import { computed, nextTick, ref, useTemplateRef, watch } from 'vue'
|
||||
import { useScroll } from '@vueuse/core'
|
||||
import type { User } from '@/stores/users.ts'
|
||||
import { useChatsStore } from '@/stores/chats.ts'
|
||||
|
||||
const area = useTemplateRef('messageArea')
|
||||
const chatsStore = useChatsStore()
|
||||
|
||||
// const area = useTemplateRef('messageArea')
|
||||
// const { y, arrivedState } = useScroll(area)
|
||||
|
||||
// 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',
|
||||
})
|
||||
|
||||
const messages = ref([])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex h-full flex-col overflow-hidden">
|
||||
<div class="grow-0">
|
||||
<slot name="toolbar" :user="user" />
|
||||
<div class="grow-0" v-if="chatsStore.selectedChat">
|
||||
<slot name="toolbar" :toolBarData="chatsStore.getChatInfo(chatsStore.selectedChat)" />
|
||||
</div>
|
||||
<div class="px-8 gap-2 grow flex flex-col-reverse overflow-y-auto" ref="messageArea">
|
||||
<slot :messages="messages" />
|
||||
|
||||
@@ -7,29 +7,6 @@ const { messages } = defineProps<{ messages: Message[] }>()
|
||||
|
||||
<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>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
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 MessagesList from '@/components/Messages/MessagesList.vue'
|
||||
import { useChatsStore } from '@/stores/chats.ts'
|
||||
|
||||
const authStore = useAuthStore()
|
||||
const chatsStore = useChatsStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-full bg-gray-100">
|
||||
<div class="flex flex-col h-full">
|
||||
<MessagesForm>
|
||||
<template #toolbar="{ user }">
|
||||
<MessageToolbar :user />
|
||||
<MessagesForm v-if="chatsStore.selected.length">
|
||||
<template #toolbar="{ toolBarData }">
|
||||
<MessageToolbar :name="toolBarData.name" />
|
||||
</template>
|
||||
<template #default="{ messages }">
|
||||
<MessagesList :messages />
|
||||
|
||||
@@ -23,20 +23,17 @@ function onStartChat(userId: number) {
|
||||
|
||||
socketsStore.send({
|
||||
type: SocketDataReq.CREATE_CHAT,
|
||||
data: {
|
||||
userId: userId,
|
||||
},
|
||||
data: { userId: userId },
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col h-full">
|
||||
<VToolbar class="px-2">
|
||||
<VToolbar theme="dark" class="px-2">
|
||||
<BackToChats class="mr-2" />
|
||||
<VSheet class="w-full">
|
||||
<VTextField prepend-inner-icon="mdi-magnify" placeholder="search contacts" />
|
||||
</VSheet>
|
||||
|
||||
<VTextField bg-color="black" prepend-inner-icon="mdi-magnify" placeholder="search contacts" />
|
||||
</VToolbar>
|
||||
|
||||
<VList>
|
||||
|
||||
@@ -33,7 +33,12 @@ const avatarText = computed(() => {
|
||||
</template>
|
||||
|
||||
<template #append>
|
||||
<VBtn icon="mdi-message" color="default" slim size="small" @click="emit('click', user.id)" />
|
||||
<VBtn
|
||||
icon="mdi-message-outline"
|
||||
variant="plain"
|
||||
size="small"
|
||||
@click="emit('click', user.id)"
|
||||
/>
|
||||
</template>
|
||||
</VListItem>
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import type { User } from '@/stores/users.ts'
|
||||
import type { Message } from '@/stores/messages.ts'
|
||||
import { useAuthStore } from '@/stores/auth.ts'
|
||||
|
||||
export interface Chat {
|
||||
id: string
|
||||
@@ -12,8 +13,31 @@ export interface Chat {
|
||||
}
|
||||
|
||||
export const useChatsStore = defineStore('chats', () => {
|
||||
const authStore = useAuthStore()
|
||||
const chats = ref<Chat[]>([])
|
||||
const selected = ref<string>()
|
||||
const selected = ref<string[]>([])
|
||||
|
||||
return { chats, selected }
|
||||
const selectedChat = computed(() => {
|
||||
const chatId = selected.value[0]
|
||||
|
||||
return chats.value.find((chat: Chat) => {
|
||||
return chat.id === chatId
|
||||
})
|
||||
})
|
||||
|
||||
function getChatInfo(chat: Chat) {
|
||||
switch (chat.typeId) {
|
||||
case 1:
|
||||
const user = chat.users.find((user) => {
|
||||
return user.id !== authStore.me?.id
|
||||
})
|
||||
return user ?? chat
|
||||
case 2:
|
||||
return chat
|
||||
default:
|
||||
return chat
|
||||
}
|
||||
}
|
||||
|
||||
return { chats, selected, selectedChat, getChatInfo }
|
||||
})
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export type SelectedMenu = 'chats' | 'users' | 'settings'
|
||||
export type MenuItems = 'chats' | 'users' | 'settings'
|
||||
|
||||
export const useMenuStore = defineStore('menu', () => {
|
||||
const selected = ref<SelectedMenu>('chats')
|
||||
const selected = ref<MenuItems[]>(['chats'])
|
||||
|
||||
return { selected }
|
||||
})
|
||||
|
||||
@@ -76,8 +76,9 @@ export const useSocketsStore = defineStore('sockets', () => {
|
||||
const idx = chatsStore.chats.findIndex((chat) => chat.id === data.id)
|
||||
if (idx < 0) chatsStore.chats.push(data)
|
||||
|
||||
menuStore.selected = 'chats'
|
||||
chatsStore.selected = data.id
|
||||
console.log(data.id)
|
||||
menuStore.selected = ['chats']
|
||||
chatsStore.selected = [data.id]
|
||||
}
|
||||
|
||||
break
|
||||
@@ -114,6 +115,7 @@ export const useSocketsStore = defineStore('sockets', () => {
|
||||
}
|
||||
|
||||
const send = (data: unknown) => {
|
||||
console.log(COMMAND.SEND, data)
|
||||
postMessage(COMMAND.SEND, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ onMounted(() => {
|
||||
</LeftPane>
|
||||
</div>
|
||||
<div class="md:w-2/3 sm:w-1/2 w-1/2">
|
||||
<RightPane></RightPane>
|
||||
<RightPane />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user