Browse Source

聊天支持识别url

master
xsx 1 year ago
parent
commit
c81ef0f2b5
  1. 6
      im-uniapp/common/emotion.js
  2. 15
      im-uniapp/common/url.js
  3. 11
      im-uniapp/components/chat-message-item/chat-message-item.vue
  4. 18
      im-uniapp/im.scss
  5. 2
      im-uniapp/main.js
  6. 15
      im-web/src/api/url.js
  7. 15
      im-web/src/components/chat/ChatMessageItem.vue
  8. 2
      im-web/src/main.js

6
im-uniapp/common/emotion.js

@ -26,7 +26,11 @@ let transform = (content, extClass) => {
let textToPath = (emoText) => {
let word = emoText.replace(/\#|\;/gi, '');
let idx = emoTextList.indexOf(word);
return `/static/emoji/${idx}.gif`;
let baseUrl = "/"
// #ifdef H5
baseUrl = window.location.pathname;
// #endif
return `${baseUrl}static/emoji/${idx}.gif`;
}

15
im-uniapp/common/url.js

@ -0,0 +1,15 @@
let replaceURLWithHTMLLinks = (content, color) => {
// 使用正则表达式匹配更广泛的URL格式
const urlRegex = /(?:https?:\/\/[^\s]+|www\.[^\s]+)/g;
return content.replace(urlRegex, (url) => {
// 如果URL不以http(s)://开头,则添加http://前缀
if (!url.startsWith("http")) {
url = "http://" + url;
}
return `<a href="${url}" target="_blank" style="color: ${color};text-decoration: underline;">${url}</a>`;
});
}
export default {
replaceURLWithHTMLLinks
}

11
im-uniapp/components/chat-message-item/chat-message-item.vue

@ -17,7 +17,8 @@
<view class="chat-msg-bottom">
<view v-if="msgInfo.type == $enums.MESSAGE_TYPE.TEXT">
<long-press-menu :items="menuItems" @select="onSelectMenu">
<rich-text class="chat-msg-text" :nodes="$emo.transform(msgInfo.content,'emoji-normal')"></rich-text>
<up-parse class="chat-msg-text" :showImgMenu="false" :content="nodesText"></up-parse>
<!-- <rich-text class="chat-msg-text" :nodes="nodesText"></rich-text> -->
</long-press-menu>
</view>
<view class="chat-msg-image" v-if="msgInfo.type == $enums.MESSAGE_TYPE.IMAGE">
@ -47,7 +48,8 @@
<text title="发送失败" v-if="loadFail" @click="onSendFail"
class="send-fail iconfont icon-warning-circle-fill"></text>
</view>
<long-press-menu v-if="msgInfo.type == $enums.MESSAGE_TYPE.AUDIO" :items="menuItems" @select="onSelectMenu">
<long-press-menu v-if="msgInfo.type == $enums.MESSAGE_TYPE.AUDIO" :items="menuItems"
@select="onSelectMenu">
<view class="chat-msg-audio chat-msg-text" @click="onPlayAudio()">
<text class="iconfont icon-voice-play"></text>
<text class="chat-audio-text">{{ JSON.parse(msgInfo.content).duration + '"' }}</text>
@ -230,6 +232,11 @@ export default {
isNormal() {
const type = this.msgInfo.type;
return this.$msgType.isNormal(type) || this.$msgType.isAction(type)
},
nodesText() {
let color = this.msgInfo.selfSend ? 'white' : '';
let text = this.$url.replaceURLWithHTMLLinks(this.msgInfo.content, color)
return this.$emo.transform(text, 'emoji-normal')
}
}

18
im-uniapp/im.scss

@ -174,19 +174,19 @@ button[size='mini'] {
}
.emoji-large {
width: 64rpx;
height: 64rpx;
vertical-align: bottom;
width: 64rpx !important;
height: 64rpx !important;
vertical-align: bottom !important;
}
.emoji-normal {
width: 54rpx;
height: 54rpx;
vertical-align: bottom;
width: 54rpx !important;
height: 54rpx !important;
vertical-align: bottom !important;
}
.emoji-small {
width: 36rpx;
height: 36rpx;
vertical-align: bottom;
width: 36rpx !important;
height: 36rpx !important;
vertical-align: bottom !important;
}

2
im-uniapp/main.js

@ -1,6 +1,7 @@
import App from './App'
import request from './common/request';
import emotion from './common/emotion.js';
import url from './common/url.js';
import * as enums from './common/enums.js';
import * as date from './common/date';
import * as socketApi from './common/wssocket';
@ -39,6 +40,7 @@ export function createApp() {
app.config.globalProperties.$wsApi = socketApi;
app.config.globalProperties.$msgType = messageType;
app.config.globalProperties.$emo = emotion;
app.config.globalProperties.$url = url;
app.config.globalProperties.$enums = enums;
app.config.globalProperties.$date = date;
app.config.globalProperties.$rc = recorder;

15
im-web/src/api/url.js

@ -0,0 +1,15 @@
let replaceURLWithHTMLLinks = (content, color) => {
// 使用正则表达式匹配更广泛的URL格式
const urlRegex = /(?:https?:\/\/[^\s]+|www\.[^\s]+)/g;
return content.replace(urlRegex, (url) => {
// 如果URL不以http(s)://开头,则添加http://前缀
if (!url.startsWith("http")) {
url = "http://" + url;
}
return `<a href="${url}" target="_blank" style="color: ${color};text-decoration: underline;">${url}</a>`;
});
}
export default {
replaceURLWithHTMLLinks
}

15
im-web/src/components/chat/ChatMessageItem.vue

@ -22,7 +22,7 @@
<div class="chat-msg-bottom" @contextmenu.prevent="showRightMenu($event)">
<div ref="chatMsgBox">
<span class="chat-msg-text" v-if="msgInfo.type == $enums.MESSAGE_TYPE.TEXT"
v-html="$emo.transform(msgInfo.content)"></span>
v-html="htmlText"></span>
<div class="chat-msg-image" v-if="msgInfo.type == $enums.MESSAGE_TYPE.IMAGE">
<div class="img-load-box" v-loading="loading" element-loading-text="上传中.."
element-loading-background="rgba(0, 0, 0, 0.4)">
@ -51,10 +51,10 @@
<audio controls :src="JSON.parse(msgInfo.content).url"></audio>
</div>
<div class="chat-action chat-msg-text" v-if="isAction">
<span v-if="msgInfo.type == $enums.MESSAGE_TYPE.ACT_RT_VOICE" title="重新呼叫" @click="$emit('call')"
class="iconfont icon-chat-voice"></span>
<span v-if="msgInfo.type == $enums.MESSAGE_TYPE.ACT_RT_VIDEO" title="重新呼叫" @click="$emit('call')"
class="iconfont icon-chat-video"></span>
<span v-if="msgInfo.type == $enums.MESSAGE_TYPE.ACT_RT_VOICE" title="重新呼叫"
@click="$emit('call')" class="iconfont icon-chat-voice"></span>
<span v-if="msgInfo.type == $enums.MESSAGE_TYPE.ACT_RT_VIDEO" title="重新呼叫"
@click="$emit('call')" class="iconfont icon-chat-video"></span>
<span>{{ msgInfo.content }}</span>
</div>
<div class="chat-msg-status" v-if="!isAction">
@ -203,6 +203,11 @@ export default {
isNormal() {
const type = this.msgInfo.type;
return this.$msgType.isNormal(type) || this.$msgType.isAction(type)
},
htmlText() {
let color = this.msgInfo.selfSend ? 'white' : '';
let text = this.$url.replaceURLWithHTMLLinks(this.msgInfo.content, color)
return this.$emo.transform(text)
}
}
}

2
im-web/src/main.js

@ -9,6 +9,7 @@ import httpRequest from './api/httpRequest';
import * as socketApi from './api/wssocket';
import * as messageType from './api/messageType';
import emotion from './api/emotion.js';
import url from './api/url.js';
import element from './api/element.js';
import store from './store';
import * as enums from './api/enums.js';
@ -22,6 +23,7 @@ Vue.prototype.$msgType = messageType
Vue.prototype.$date = date;
Vue.prototype.$http = httpRequest // http请求方法
Vue.prototype.$emo = emotion; // emo表情
Vue.prototype.$url = url; // url转换
Vue.prototype.$elm = element; // 元素操作
Vue.prototype.$enums = enums; // 枚举
Vue.prototype.$eventBus = new Vue(); // 全局事件

Loading…
Cancel
Save