Последняя версия с сервера прошлого разработчика
This commit is contained in:
263
resources/js/Pages/Messenger/Index.vue
Executable file
263
resources/js/Pages/Messenger/Index.vue
Executable file
@@ -0,0 +1,263 @@
|
||||
<template>
|
||||
<meta-head title="Мессенджер"></meta-head>
|
||||
<div class="flex sm:grid grid-cols-12 h-full overflow-hidden">
|
||||
<!-- flex-shrink-0 -->
|
||||
<div ref="userSidebar" class="h-full sm:h-auto transition-transform z-50 absolute transform-gpu -translate-x-full w-64 sm:relative sm:transform-none sm:w-auto col-span-4 bg-indigo-200 border-l border-r border-indigo-300 py-7">
|
||||
<div class="mb-7 px-2 xl:px-8">
|
||||
<div class="relative">
|
||||
<text-input v-model="inputSearchRoom"
|
||||
class="pr-12 focus:ring-4 focus:ring-offset-1 focus:ring-orange focus:ring-opacity-20 focus:ring-offset-orange focus:border-transparent text-gray border border-indigo-300 bg-indigo-200 rounded-md placeholder-gray-light w-full" placeholder="Поиск"
|
||||
/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24"
|
||||
height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="text-gray-light absolute right-3 top-2"
|
||||
><circle cx="11" cy="11"
|
||||
r="8"
|
||||
></circle><line x1="21" y1="21"
|
||||
x2="16.65" y2="16.65"
|
||||
></line></svg>
|
||||
</div>
|
||||
<div class="flex flex-col lg:flex-row lg:space-x-6 mt-2">
|
||||
<div class="flex items-center">
|
||||
<input id="room-search-1" v-model="typeSearch"
|
||||
:value="1" type="radio"
|
||||
class="text-orange border-gray-light focus:ring-transparent focus:ring-offset-transparent cursor-pointer"
|
||||
>
|
||||
<label for="room-search-1" class="cursor-pointer select-none ml-2 text-gray-light text-sm">по сообщениям</label>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<input id="room-search-2" v-model="typeSearch"
|
||||
:value="2" type="radio"
|
||||
class="text-orange border-gray-light focus:ring-transparent focus:ring-offset-transparent cursor-pointer"
|
||||
>
|
||||
<label for="room-search-2" class="cursor-pointer select-none ml-2 text-gray-light text-sm">по пользователям</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<button class="default mb-2 text-orange text-sm mr-1" @click="openFriendList">
|
||||
открыть список друзей
|
||||
</button>
|
||||
</div>
|
||||
<div data-simplebar class="messsage-height overflow-auto">
|
||||
<div class="divide-y divide-indigo-300 border-t border-b border-indigo-300">
|
||||
<board-room-list v-for="room in userRooms" :key="room.id"
|
||||
class="pt-5 pb-5"
|
||||
:class="{ 'bg-indigo-300': room.classActive }"
|
||||
:room="room"
|
||||
@select-room="changeRoom"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 w-full sm:flex-none sm:w-auto col-span-8 bg-indigo-200 overflow-hidden relative">
|
||||
<button class="default text-center left-2 top-3 absolute z-40 flex sm:hidden items-center text-white text-xs" @click="openSidebar">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24"
|
||||
height="24" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-menu"
|
||||
><line x1="3" y1="12"
|
||||
x2="21" y2="12"
|
||||
></line><line x1="3" y1="6"
|
||||
x2="21" y2="6"
|
||||
></line><line x1="3" y1="18"
|
||||
x2="21" y2="18"
|
||||
></line></svg>
|
||||
<span class="ml-1">открыть список пользователей</span>
|
||||
</button>
|
||||
<board-message :room-id="selectRoom" :user="selectUser"
|
||||
:frozen="selectFrozenRoom" :search="searchOnlyMessage"
|
||||
@disable="interactDisable" @last-message="updateRoom"
|
||||
@change-room="touchRoom" @leave-room="leaveRoom"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, toRef, watch } from 'vue'
|
||||
import { onClickOutside } from '@vueuse/core'
|
||||
import { usePage } from '@inertiajs/inertia-vue3'
|
||||
import { Inertia } from '@inertiajs/inertia'
|
||||
import debounce from 'lodash/debounce'
|
||||
import pickBy from 'lodash/pickBy'
|
||||
|
||||
import Layout from '@/Shared/Layout.vue'
|
||||
import MetaHead from '@/Shared/MetaHead.vue'
|
||||
import TextInput from '@/Shared/Form/TextInput.vue'
|
||||
import BoardRoomList from '@/Shared/Messanger/BoardRoomList.vue'
|
||||
import BoardMessage from '@/Shared/Messanger/BoardMessage.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MetaHead,
|
||||
TextInput,
|
||||
BoardRoomList,
|
||||
BoardMessage,
|
||||
},
|
||||
layout: Layout,
|
||||
|
||||
props: {
|
||||
rooms: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
roomSearch: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
|
||||
setup(props){
|
||||
var inputSearchRoom = ref(props.roomSearch)
|
||||
const typeSearch = ref(1)
|
||||
const searchOnlyMessage = ref('')
|
||||
var userRooms = toRef(props, 'rooms')
|
||||
|
||||
var selectUser = ref(null)
|
||||
var selectRoom = ref(0)
|
||||
var selectFrozenRoom = ref(false)
|
||||
|
||||
var userSidebar = ref(null)
|
||||
var canChangeRoom = ref(true)
|
||||
|
||||
watch(inputSearchRoom, debounce((search) => {
|
||||
selectUser.value = null
|
||||
selectRoom.value = 0
|
||||
if(typeSearch.value === 1){
|
||||
searchOnlyMessage.value = search
|
||||
}
|
||||
Inertia.get(route('messenger.index'), pickBy({ search: search, type: search ? typeSearch.value : null }), { preserveState: true })
|
||||
}, 500))
|
||||
|
||||
watch(typeSearch, () => {
|
||||
inputSearchRoom.value = ''
|
||||
})
|
||||
|
||||
const checkSelectedActiveUser = () => {
|
||||
const activeRoom = userRooms.value.find(userRoom => userRoom.classActive === true)
|
||||
if(activeRoom){
|
||||
selectUser.value = activeRoom.correspond
|
||||
selectRoom.value = activeRoom.id
|
||||
selectFrozenRoom.value = activeRoom.is_freeze
|
||||
}
|
||||
}
|
||||
checkSelectedActiveUser()
|
||||
|
||||
function openFriendList() {
|
||||
selectUser.value = null
|
||||
selectRoom.value = 0
|
||||
userRooms.value.forEach(item => item.classActive = false)
|
||||
}
|
||||
|
||||
const touchRoom = (id) => {
|
||||
const activeRoom = userRooms.value.find(userRoom => userRoom.id === id)
|
||||
if(activeRoom){
|
||||
activeRoom.classActive = true
|
||||
selectUser.value = activeRoom.correspond
|
||||
selectRoom.value = activeRoom.id
|
||||
selectFrozenRoom.value = activeRoom.is_freeze
|
||||
}
|
||||
}
|
||||
|
||||
const leaveRoom = () => {
|
||||
selectRoom.value = 0
|
||||
selectUser.value = null
|
||||
selectFrozenRoom.value = false
|
||||
}
|
||||
|
||||
|
||||
const changeRoom = (room) => {
|
||||
closeSidebar()
|
||||
if(canChangeRoom.value){
|
||||
selectRoom.value = room.id
|
||||
selectUser.value = room.correspond
|
||||
selectFrozenRoom.value = room.is_freeze
|
||||
const lastActiveRoom = userRooms.value.find(userRoom => userRoom.classActive === true)
|
||||
if(lastActiveRoom){
|
||||
lastActiveRoom.classActive = false
|
||||
}
|
||||
const nowActiveRoom = userRooms.value.find(userRoom => userRoom.id === room.id)
|
||||
nowActiveRoom.classActive = true
|
||||
|
||||
if(!nowActiveRoom.is_my_message && !nowActiveRoom.is_reading){
|
||||
nowActiveRoom.is_reading = true
|
||||
usePage().props.value.message_reading_count--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let openSidebar = () => {
|
||||
if (window.matchMedia('(max-width: 640px)').matches) {
|
||||
userSidebar.value.classList.remove('-translate-x-full')
|
||||
userSidebar.value.classList.add('-translate-x-0')
|
||||
userSidebar.value.classList.add('shadow-classic')
|
||||
}
|
||||
}
|
||||
|
||||
let closeSidebar = () => {
|
||||
if (window.matchMedia('(max-width: 640px)').matches) {
|
||||
userSidebar.value.classList.add('-translate-x-full')
|
||||
userSidebar.value.classList.remove('-translate-x-0')
|
||||
userSidebar.value.classList.remove('shadow-classic')
|
||||
}
|
||||
}
|
||||
|
||||
let interactDisable = (type) => {
|
||||
if(type === true){
|
||||
canChangeRoom.value = false
|
||||
}else{
|
||||
canChangeRoom.value = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let updateRoom = (message) => {
|
||||
const upRoom = userRooms.value.find(userRoom => userRoom.id === message.chat_room_id)
|
||||
upRoom.message = message.message
|
||||
upRoom.is_my_message = true
|
||||
upRoom.is_reading = false
|
||||
upRoom.updated_at = message.updated_at_room
|
||||
upRoom.updated_at_human = message.updated_at_room_human
|
||||
|
||||
userRooms.value.sort(function(a, b) {
|
||||
if (a.updated_at > b.updated_at) {
|
||||
return -1
|
||||
}
|
||||
if (a.updated_at < b.updated_at) {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
}
|
||||
|
||||
if (window.matchMedia('(max-width: 640px)').matches) {
|
||||
onClickOutside(userSidebar, () => {
|
||||
closeSidebar()
|
||||
})
|
||||
}
|
||||
return {
|
||||
changeRoom,
|
||||
selectUser,
|
||||
userRooms,
|
||||
selectRoom,
|
||||
openSidebar,
|
||||
userSidebar,
|
||||
closeSidebar,
|
||||
interactDisable,
|
||||
updateRoom,
|
||||
inputSearchRoom,
|
||||
typeSearch,
|
||||
searchOnlyMessage,
|
||||
selectFrozenRoom,
|
||||
touchRoom,
|
||||
leaveRoom,
|
||||
openFriendList,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user