Commit 0f5069c2 authored by chenqikuai's avatar chenqikuai

update

parent b1a9feea
......@@ -2,7 +2,7 @@
const colors = {
primary: '#1888FA',
secondary: '#E8F3FF',
secondary: '#3E4FAF',
'secondary-focus': '#D6E3F0',
dark: '#24374E',
negative: '#db394c',
......
<template>
<div class="flex flex-col flex-nowrap h-full text-base bg-gray-50 h-screen">
<div class="flex flex-col flex-nowrap text-base bg-gray-50 h-screen">
<!-- 没连上时界面上只有一个返回按钮 -->
<!-- 👇是返回按钮 -->
<!-- <div
......@@ -134,15 +134,16 @@ export default defineComponent({
// 收到的非本笔订单的消息不处理
// if (msg.orderid !== orderid) return;
msg && messageStore.displayNewMessage({
content: msg.content,
from: msg.from,
uuid: msg.uuid,
state: null,
type: (msg.type || 0) as ChatMessageTypes,
datetime: msg.datetime,
logid: msg.logid,
});
msg &&
messageStore.displayNewMessage({
content: msg.content,
from: msg.from,
uuid: msg.uuid,
state: null,
type: (msg.type || 0) as ChatMessageTypes,
datetime: msg.datetime,
logid: msg.logid,
});
};
// 连接后,指定每次断开连接要做的事
......
<template>
<!-- style="flex-basis: 0px" 是为了兼容 iOS 和 macOS 下的 Safari 浏览器,如果没有这个样式,整个聊天列表无法显示 -->
<q-scroll-area ref="scrollArea" class="flex-grow" style="flex-basis: 0px" :visible="false">
<q-pull-to-refresh
<!-- style="flex-basis: 0px" 是为了兼容 iOS 和 macOS 下的 Safari 浏览器,如果没有这个样式,整个聊天列表无法显示 -->
<q-scroll-area
ref="scrollArea"
class="flex-grow"
style="flex-basis: 0px"
:visible="false"
>
<!-- <q-pull-to-refresh
v-if="messages.length"
@refresh="loadMore"
:disable="noMoreMessages || messages.length === 0"
icon="history"
class="h-full w-full absolute"
>
<div class="text-center py-2.5 text-xs font-medium text-subtle">
> -->
<!-- <div class="text-center py-2.5 text-xs font-medium text-subtle">
<div v-if="noMoreMessages && messages.length >= 10">没有更多消息</div>
<div v-else-if="!noMoreMessages && messages.length >= 10">
{{ isMobile ? '下滑加载更多' : '按住鼠标向下拖拽以加载更多' }}
</div>
</div>
<ChatContentMessageVue
v-for="message in messages"
:key="message.uuid"
:id="message.uuid"
:content="message.content"
:fromMyself="myid == message.from"
:time="formatDate(message.datetime, 'MM月DD日 HH:mm')"
:uuid="message.uuid"
:type="message.type"
:state="message.state"
:hideDatetime="message.hideDatetime"
:uploadProgress="message.uploadProgress"
/>
</q-pull-to-refresh>
</q-scroll-area>
</div> -->
<ChatContentMessageVue
v-for="message in messages"
:key="message.uuid"
:id="message.uuid"
:content="message.content"
:fromMyself="myid == message.from"
:time="formatDate(message.datetime, 'MM月DD日 HH:mm')"
:uuid="message.uuid"
:type="message.type"
:state="message.state"
:hideDatetime="message.hideDatetime"
:uploadProgress="message.uploadProgress"
/>
<!-- </q-pull-to-refresh> -->
</q-scroll-area>
</template>
<script lang="ts">
import { defineComponent, nextTick, watch } from 'vue'
import { from } from '@/store/appCallerStore'
import { DisplayMessage, messageStore } from '@/store/messagesStore'
import useScrollTo from '@/composables/useScrollTo'
import ChatContentMessageVue from './ChatContentMessage.vue'
import { date, Platform } from 'quasar'
import { defineComponent, nextTick, watch } from "vue";
import { from } from "@/store/appCallerStore";
import { DisplayMessage, messageStore } from "@/store/messagesStore";
import useScrollTo from "@/composables/useScrollTo";
import ChatContentMessageVue from "./ChatContentMessage.vue";
import { date, Platform } from "quasar";
export default defineComponent({
components: { ChatContentMessageVue },
setup() {
const messages = messageStore.messages
const noMoreMessages = messageStore.noMoreHistoryMessages
const myid = from
const formatDate = date.formatDate
const isMobile = Platform.is.mobile
components: { ChatContentMessageVue },
setup() {
const messages = messageStore.messages;
const noMoreMessages = messageStore.noMoreHistoryMessages;
const myid = from;
const formatDate = date.formatDate;
const isMobile = Platform.is.mobile;
// 监听「下拉加载更多」操作,记录当前的第一条消息 id
let firstMessageSnapshot: DisplayMessage
const loadMore = (done?: () => void) => {
firstMessageSnapshot = messages[0]
retrieveMessages().then(() => done && done())
}
// 监听「下拉加载更多」操作,记录当前的第一条消息 id
let firstMessageSnapshot: DisplayMessage;
const loadMore = (done?: () => void) => {
firstMessageSnapshot = messages[0];
retrieveMessages().then(() => done && done());
};
const retrieveMessages = (): Promise<void> => {
return new Promise((resolve) => {
messageStore.retrieveMessages().then(() => resolve())
})
}
retrieveMessages()
const retrieveMessages = (): Promise<void> => {
return new Promise((resolve) => {
messageStore.retrieveMessages().then(() => resolve());
});
};
// retrieveMessages();
// 收到新消息时滚动至底部
const { scrollToBottom, scrollArea, scrollToElement } = useScrollTo()
watch(messages, () => {
nextTick(() => {
if (messageStore.appendingNewMessage.value) {
scrollToBottom()
} else {
scrollToElement(document.getElementById(firstMessageSnapshot.uuid))
}
})
})
// 收到新消息时滚动至底部
const { scrollToBottom, scrollArea, scrollToElement } = useScrollTo();
watch(messages, () => {
nextTick(() => {
if (messageStore.appendingNewMessage.value) {
scrollToBottom();
} else {
scrollToElement(document.getElementById(firstMessageSnapshot.uuid));
}
});
});
return { scrollToBottom, scrollArea, messages, noMoreMessages, isMobile, myid, formatDate, loadMore }
},
})
return {
scrollToBottom,
scrollArea,
messages,
noMoreMessages,
isMobile,
myid,
formatDate,
loadMore,
};
},
});
</script>
......@@ -17,74 +17,87 @@
min-w-chat-msg-avatar
w-chat-msg-avatar
h-chat-msg-avatar
rounded-lg
!rounded-md
"
>
<img :src="default_avatar_url" />
</q-avatar>
<!-- 消息气泡 -->
<div
:class="[{ 'flex-row-reverse': fromMyself }]"
class="flex items-center max-w-chat-msg-bubble"
>
<!-- 文本消息 -->
<ChatContentMessageTextVue
v-if="type === 1"
:from-myself="fromMyself"
:content="content"
/>
<div :class="[{ 'flex-row-reverse': fromMyself }]">
<div
class="text-right"
style="
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #adadad;
"
>
15990184793
</div>
<div
:class="[{ 'flex-row-reverse': fromMyself }]"
class="flex items-center max-w-chat-msg-bubble"
>
<!-- 文本消息 -->
<ChatContentMessageTextVue
v-if="type === 1"
:from-myself="fromMyself"
:content="content"
/>
<!-- 图片消息 -->
<ChatContentMessageImageVue
v-else-if="type === 3"
:from-myself="fromMyself"
:state="state"
:content="content"
:uploadProgress="uploadProgress"
/>
<!-- 图片消息 -->
<ChatContentMessageImageVue
v-else-if="type === 3"
:from-myself="fromMyself"
:state="state"
:content="content"
:uploadProgress="uploadProgress"
/>
<ChatContentMessageVideoVue
v-else-if="type === 4"
:from-myself="fromMyself"
:state="state"
:content="content"
:uploadProgress="uploadProgress"
/>
<ChatContentMessageVideoVue
v-else-if="type === 4"
:from-myself="fromMyself"
:state="state"
:content="content"
:uploadProgress="uploadProgress"
/>
<!-- 卡片消息 -->
<ChatContentMessageCardVue
v-else-if="type === 6"
:from-myself="fromMyself"
:content="content"
/>
<!-- 卡片消息 -->
<ChatContentMessageCardVue
v-else-if="type === 6"
:from-myself="fromMyself"
:content="content"
/>
<!-- 消息状态 -->
<div
class="w-10 self-stretch flex flex-row justify-center items-center"
>
<!-- 发送失败 -->
<!-- 消息状态 -->
<div
v-if="state === 'failure'"
@click="resend"
class="w-full h-full flex flex-row justify-center items-center"
class="w-10 self-stretch flex flex-row justify-center items-center"
>
<q-icon name="error" size="22px" color="negative" />
<!-- 发送失败 -->
<div
v-if="state === 'failure'"
@click="resend"
class="w-full h-full flex flex-row justify-center items-center"
>
<q-icon name="error" size="22px" color="negative" />
</div>
<!-- 正在发送 -->
<q-spinner-ios
v-else-if="state === 'pending' && !isMedia"
color="grey"
size="1.25rem"
:thickness="5"
/>
<q-icon
v-else-if="state === 'pending' && isMedia"
@click="abort"
name="cancel"
size="22px"
color="negative"
/>
</div>
<!-- 正在发送 -->
<q-spinner-ios
v-else-if="state === 'pending' && !isMedia"
color="grey"
size="1.25rem"
:thickness="5"
/>
<q-icon
v-else-if="state === 'pending' && isMedia"
@click="abort"
name="cancel"
size="22px"
color="negative"
/>
</div>
</div>
</div>
......
<template>
<div
:class="[
fromMyself ? 'bg-secondary' : 'bg-white',
fromMyself ? 'rounded-chat-msg-bubble-myself' : 'rounded-chat-msg-bubble-opposite',
]"
class="py-3 px-4 max-w-chat-msg-text break-all"
<div
:class="[
fromMyself ? 'bg-secondary text-white' : 'bg-white',
fromMyself ? 'message-box-self' : 'message-box-other',
]"
class="py-3 px-4 max-w-chat-msg-text break-all message-box rounded-md"
>
<a
v-if="isUrlMessage"
:href="prependHttp(textMessage)"
class="text-primary enable-touch"
target="_blank"
rel="noopener noreferrer"
>
<a
v-if="isUrlMessage"
:href="prependHttp(textMessage)"
class="text-primary enable-touch"
target="_blank"
rel="noopener noreferrer"
>
{{ textMessage }}
</a>
<div v-else class="enable-touch">{{ textMessage }}</div>
</div>
{{ textMessage }}
</a>
<div v-else class="enable-touch">{{ textMessage }}</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue'
import isUrl from '@/utils/is-url'
import prependHttp from 'prepend-http'
import { computed, defineComponent } from "vue";
import isUrl from "@/utils/is-url";
import prependHttp from "prepend-http";
export default defineComponent({
props: { fromMyself: Boolean, content: Object },
props: { fromMyself: Boolean, content: Object },
setup(props) {
const textMessage = computed(() => props.content?.content)
const isUrlMessage = computed(() => isUrl(textMessage.value))
setup(props) {
const textMessage = computed(() => props.content?.content);
const isUrlMessage = computed(() => isUrl(textMessage.value));
return { isUrlMessage, prependHttp, textMessage }
},
})
return { isUrlMessage, prependHttp, textMessage };
},
});
</script>
<style scoped></style>
<style scoped>
.message-box {
position: relative;
}
.message-box-self::after {
content: "";
position: absolute;
right: 0;
top: 0px;
transform: translate(100%, 15px);
border-top: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid transparent;
border-left: 6px solid #3e4faf;
}
.message-box-other::after {
content: "";
position: absolute;
left: 0;
top: 0px;
transform: translate(-100%, 15px);
border-top: 6px solid transparent;
border-right: 6px solid white;
border-bottom: 6px solid transparent;
border-left: 6px solid transparent;
}
</style>
......@@ -78,6 +78,7 @@ module.exports = {
extend: {},
padding: ['responsive', 'important'],
backgroundColor: ['responsive', 'important'],
borderRadius: ['responsive', 'important'],
},
plugins: [
plugin(function ({ addVariant }) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment