show map
This commit is contained in:
Vendored
+1
@@ -39,6 +39,7 @@ declare module 'vue' {
|
||||
LinkShareButton: typeof import('./src/components/link/LinkShareButton.vue')['default']
|
||||
LinkShareTelegramButton: typeof import('./src/components/link/LinkShareTelegramButton.vue')['default']
|
||||
ManagePlacementInstructions: typeof import('./src/components/manage/ManagePlacementInstructions.vue')['default']
|
||||
MapCoors: typeof import('./src/components/MapCoors.vue')['default']
|
||||
ProgressSpinner: typeof import('primevue/progressspinner')['default']
|
||||
QRCodeCard: typeof import('./src/components/manage/QRCodeCard.vue')['default']
|
||||
QRCodePlacementIcon: typeof import('./src/components/manage/QRCodePlacementIcon.vue')['default']
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<iframe v-if="src" :src allowfullscreen class="w-full h-auto aspect-square" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
coords: Omit<GeolocationPosition['coords'], 'toJSON'>
|
||||
}>()
|
||||
|
||||
const src = computed(
|
||||
() =>
|
||||
`https://yandex.ru/map-widget/v1/?ll=${encodeURIComponent(props.coords.longitude + ',' + props.coords.latitude)}&mode=routes&rtext=~${encodeURIComponent(props.coords.latitude + ',' + props.coords.longitude)}&rtt=auto&ruri=~&z=18`,
|
||||
)
|
||||
</script>
|
||||
@@ -1,42 +1,52 @@
|
||||
<template>
|
||||
<div class="place-self-stretch flex flex-col">
|
||||
<div
|
||||
v-for="message in messages"
|
||||
:key="message._id"
|
||||
:id="`msg-${message.created_at}`"
|
||||
class="mb-4 max-w-md"
|
||||
v-for="doc in docs"
|
||||
:key="doc._id"
|
||||
:id="`msg-${doc.created_at}`"
|
||||
class="mb-4"
|
||||
:class="{
|
||||
'ml-auto text-right': message.from === userRole,
|
||||
'mr-auto text-left': message.from !== userRole,
|
||||
'max-w-md': doc.type === 'message',
|
||||
'ml-auto text-right': doc.type === 'message' && doc.from === userRole,
|
||||
'mr-auto text-left': doc.type === 'message' && doc.from !== userRole,
|
||||
}"
|
||||
>
|
||||
<Card
|
||||
class="p-card-sm"
|
||||
:class="{
|
||||
'bg-blue-50 dark:bg-blue-900 border-blue-300 dark:border-blue-700 text-blue-500 dark:text-blue-200':
|
||||
message.from === userRole,
|
||||
doc.from === userRole,
|
||||
'bg-gray-50 dark:bg-gray-800 border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300':
|
||||
message.from !== userRole,
|
||||
doc.from !== userRole,
|
||||
}"
|
||||
>
|
||||
<template #content>
|
||||
{{ message.body }}
|
||||
<template v-if="doc.type === 'message'">
|
||||
{{ doc.body }}
|
||||
</template>
|
||||
<template v-if="doc.type === 'geolocation'">
|
||||
<MapCoors :coords="doc.coords" />
|
||||
</template>
|
||||
</template>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<slot
|
||||
name="endOfMessages"
|
||||
:count="messages.length"
|
||||
:lastMessage="messages.length > 0 ? messages[messages.length - 1] : null"
|
||||
:count="docs.length"
|
||||
:lastMessage="docs.length > 0 ? docs[docs.length - 1] : null"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
|
||||
import { messagesDbLocal as db, messagesDbRemote as remoteDb } from '@/api/dbs'
|
||||
import { type MessageDocument } from '@hereconnect/types'
|
||||
import {
|
||||
messagesDbLocal as db,
|
||||
messagesDbRemote as remoteDb,
|
||||
geolocationsDbRemote,
|
||||
} from '@/api/dbs'
|
||||
import { type MessageDocument, type GeolocationDocument } from '@hereconnect/types'
|
||||
|
||||
const { qr_code_uri, chat, userRole } = defineProps<{
|
||||
qr_code_uri: MessageDocument['qr_code_uri']
|
||||
@@ -45,7 +55,7 @@ const { qr_code_uri, chat, userRole } = defineProps<{
|
||||
}>()
|
||||
|
||||
// Локальные состояния
|
||||
const messages = ref<MessageDocument[]>([])
|
||||
const docs = ref<(MessageDocument | GeolocationDocument)[]>([])
|
||||
|
||||
let changesSubscription: PouchDB.Core.Changes<MessageDocument> | null = null
|
||||
let syncMessages: PouchDB.Replication.Sync<MessageDocument> | null = null
|
||||
@@ -60,11 +70,25 @@ const messageSelector = {
|
||||
// Загрузка сообщений
|
||||
async function loadMessages() {
|
||||
try {
|
||||
const result = await db.find({
|
||||
selector: messageSelector,
|
||||
limit: Number.MAX_SAFE_INTEGER,
|
||||
})
|
||||
messages.value = result.docs as MessageDocument[]
|
||||
const result = await Promise.all([
|
||||
db.find({
|
||||
selector: messageSelector,
|
||||
limit: Number.MAX_SAFE_INTEGER,
|
||||
}),
|
||||
|
||||
geolocationsDbRemote.find({
|
||||
selector: {
|
||||
type: 'geolocation',
|
||||
qr_code_uri,
|
||||
chat,
|
||||
},
|
||||
}),
|
||||
])
|
||||
|
||||
docs.value = [
|
||||
...(result[0].docs as MessageDocument[]),
|
||||
...(result[1].docs as GeolocationDocument[]),
|
||||
].sort((a, b) => (a.created_at > b.created_at ? 1 : -1))
|
||||
} catch (error) {
|
||||
console.error('Ошибка загрузки сообщений:', error)
|
||||
}
|
||||
@@ -81,16 +105,16 @@ function watchChanges() {
|
||||
})
|
||||
.on('change', (change: { doc?: MessageDocument }) => {
|
||||
if (change.doc) {
|
||||
const index = messages.value.findIndex((m) => m._id === change.doc!._id)
|
||||
const index = docs.value.findIndex((m) => m._id === change.doc!._id)
|
||||
if (index === -1) {
|
||||
// Если сообщения нет, добавляем его
|
||||
messages.value.push(change.doc)
|
||||
docs.value.push(change.doc)
|
||||
} else {
|
||||
// Если сообщение существует, обновляем его
|
||||
messages.value[index] = change.doc
|
||||
docs.value[index] = change.doc
|
||||
}
|
||||
// Сортируем массив сообщений
|
||||
messages.value.sort((a, b) => (a.created_at > b.created_at ? 1 : -1))
|
||||
docs.value.sort((a, b) => (a.created_at > b.created_at ? 1 : -1))
|
||||
}
|
||||
})
|
||||
.on('error', (err) => {
|
||||
@@ -138,7 +162,7 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
watch(
|
||||
() => messages.value?.length,
|
||||
() => docs.value?.length,
|
||||
async () => {
|
||||
await nextTick()
|
||||
emit('scrollToBottom')
|
||||
|
||||
Reference in New Issue
Block a user