| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- <template>
- <scroll-view id="myScrollView" class="ss-chat" :scroll-x="false" :scroll-y="true" :scroll-anchoring="true"
- :scroll-into-view="toView" :class="{ spread: globalStore.spread }" :style="chatScrollStyle"
- @scroll="handlerScroll">
- <view class="ss-chat-container">
- <template v-if="globalStore.chatList" v-for="(item, index) in globalStore.chatList" :key="index">
- <ss-chat-send-message v-if="item.type == 'send_message'" :message="item.content"
- @edit-message="editMessage" />
- <ss-chat-reply v-else :reply="item" :last="index + 1 >= globalStore.chatList.length"
- @quick-send="quickSend" @change-chat="changeChat" />
- </template>
- </view>
- <view id="scrollBottom" class="scroll-bottom"></view>
- </scroll-view>
- </template>
- <script>
- import {
- useGlobalStore
- } from '@/stores/global';
- import SsChatSendMessage from '@/components/ss_chat/child/SsChatSendMessage.vue';
- import SsChatReply from '@/components/ss_chat/child/SsChatReply.vue';
- export default {
- components: {
- SsChatSendMessage,
- SsChatReply
- },
- data() {
- return {
- globalStore: useGlobalStore(),
- bottomSafe: 0,
- toView: '',
- scrollFlag: true,
- scrollViewHeight: 0,
- handlerScrollFlag: false,
- handlerScrollTimeout: false,
- innerAudioContext: null,
- scrollDirection: 'down',
- beforeScrollTop: 0
- };
- },
- computed: {
- chatScrollStyle() {
- let h = '0';
- if (this.globalStore.spread) {
- let a = this.globalStore.paddingTop + 66;
- a += (this.globalStore.inputLine <= 3 ? this.globalStore.inputLine : 3) * 10;
- a += 60;
- a += this.bottomSafe;
- h = 'height: calc(100vh - ' + a + 'px)';
- }
- return h;
- }
- },
- mounted() {
- this.setBottomSafe();
- },
- methods: {
- editMessage(message) {
- this.$emit('editMessage', message);
- },
- setBottomSafe() {
- let safeArea = uni.getSystemInfoSync().safeArea;
- this.bottomSafe = uni.getSystemInfoSync().screenHeight - safeArea.bottom;
- },
- scrollToBottom(force = false) {
- this.toView = '';
- this.getScrollViewHeight();
- this.$nextTick(() => {
- if (this.scrollFlag && this.scrollDirection == 'down' || force) {
- this.toView = 'scrollBottom';
- }
- });
- },
- newMessage() {
- this.scrollFlag = true;
- this.scrollDirection = 'down';
- this.scrollToBottom();
- },
- getScrollViewHeight() {
- const query = uni.createSelectorQuery().in(this);
- query.select('#myScrollView').boundingClientRect(res => {
- if (res) {
- this.scrollViewHeight = res.height;
- }
- }).exec();
- },
- handlerScroll(event) {
- this.$nextTick(() => {
- let scrollTop = this.scrollViewHeight + event.detail.scrollTop ?? 0;
- if (scrollTop < 50) {
- return ;
- }
- if (this.scrollFlag && this.beforeScrollTop - 100 > scrollTop) {
- this.scrollDirection = 'up'
- } else {
- this.scrollDirection = 'down'
- }
- let scrollHeight = event.detail.scrollHeight ?? 0;
- // 如果用户手动向上滚动,暂停自动滚动
- this.scrollFlag = scrollTop >= scrollHeight - 100;
- this.beforeScrollTop = scrollTop;
- });
- },
- quickSend(msg) {
- this.$emit('quickSend', msg);
- },
- changeChat() {
- this.$emit('changeChat');
- }
- }
- };
- </script>
- <style scoped lang="scss">
- .ss-chat {
- height: 0;
- overflow: hidden;
- transition: height 0.3s linear;
- overflow-anchor: auto;
- .ss-chat-container {
- margin: 0 auto;
- }
- .scroll-bottom {
- height: 6rpx;
- }
- &.spread {
- margin-bottom: 36rpx;
- }
- }
- </style>
|