|
@@ -110,10 +110,7 @@
|
|
|
</div>
|
|
|
</div> -->
|
|
|
<!-- 视频格式文件 -->
|
|
|
- <div
|
|
|
- class="message-content-image"
|
|
|
- v-if="item.type === 'video'"
|
|
|
- >
|
|
|
+ <div class="message-content-image" v-if="item.type === 'video'">
|
|
|
<video
|
|
|
style="width: 255px"
|
|
|
src="https://media.w3.org/2010/05/sintel/trailer.mp4"
|
|
@@ -248,10 +245,7 @@
|
|
|
</div>
|
|
|
</div> -->
|
|
|
<!-- 视频格式文件 -->
|
|
|
- <div
|
|
|
- class="message-content-image"
|
|
|
- v-if="item.type === 'video'"
|
|
|
- >
|
|
|
+ <div class="message-content-image" v-if="item.type === 'video'">
|
|
|
<video
|
|
|
style="width: 255px"
|
|
|
src="https://media.w3.org/2010/05/sintel/trailer.mp4"
|
|
@@ -275,7 +269,13 @@
|
|
|
<div class="tools" style="margin: 10px">
|
|
|
<el-popover placement="top" width="300" trigger="click">
|
|
|
<Emoji @addEmoji="addEmoji" />
|
|
|
- <el-button class="iconfont open_emoji_icon" style="color:rgb(44,60,80)" type="text" slot="reference"></el-button>
|
|
|
+ <el-button
|
|
|
+ class="iconfont open_emoji_icon"
|
|
|
+ style="color:rgb(44,60,80)"
|
|
|
+ type="text"
|
|
|
+ slot="reference"
|
|
|
+ ></el-button
|
|
|
+ >
|
|
|
</el-popover>
|
|
|
<el-upload
|
|
|
ref="upload"
|
|
@@ -297,16 +297,16 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="input-box">
|
|
|
- <div
|
|
|
- id="charInput"
|
|
|
+ <div
|
|
|
+ id="charInput"
|
|
|
@click="saveRangeLocal"
|
|
|
- @focus="saveRangeLocal"
|
|
|
- @input="saveRangeLocal"
|
|
|
+ @focus="saveRangeLocal"
|
|
|
+ @input="saveRangeLocal"
|
|
|
@keydown.enter="stopPropagation"
|
|
|
@keyup.enter="sendMsg"
|
|
|
- class="chatframe_input_con scrollbar"
|
|
|
- contenteditable="true">
|
|
|
- </div>
|
|
|
+ class="chatframe_input_con scrollbar"
|
|
|
+ contenteditable="true"
|
|
|
+ ></div>
|
|
|
<div class="send-footer">
|
|
|
<el-button
|
|
|
type="info"
|
|
@@ -330,25 +330,25 @@
|
|
|
import { isUrl, parseHtml } from "@/utils/common";
|
|
|
import Emoji from "./Emoji.vue";
|
|
|
import { mapState, mapActions } from "vuex";
|
|
|
-let emojiData = require('./../assets/emoji/emoji.json')
|
|
|
-import request from '@/api/require'
|
|
|
+let emojiData = require("./../assets/emoji/emoji.json");
|
|
|
+import request from "@/api/require";
|
|
|
export default {
|
|
|
name: "ChatFrame",
|
|
|
props: ["selected", "tab"],
|
|
|
components: {
|
|
|
- Emoji,
|
|
|
+ Emoji
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
baseUrl: "http://192.168.100.8:3000/",
|
|
|
emojiIcon: emojiData.icon,
|
|
|
- inputRange: '', // 光标
|
|
|
- emojiPath: new Map(), // emoji表情地址map对象,
|
|
|
+ inputRange: "", // 光标
|
|
|
+ emojiPath: new Map(), // emoji表情地址map对象,
|
|
|
msg: "",
|
|
|
friend_record_list: [],
|
|
|
room_record_list: [],
|
|
|
messageType: "",
|
|
|
- uploadProgress: false,
|
|
|
+ uploadProgress: false
|
|
|
};
|
|
|
},
|
|
|
computed: {
|
|
@@ -363,38 +363,36 @@ export default {
|
|
|
}),
|
|
|
...mapState({
|
|
|
roomRecord: state => state.chat.roomRecord
|
|
|
- }),
|
|
|
+ })
|
|
|
},
|
|
|
watch: {
|
|
|
selected(newVal, o) {
|
|
|
- if (this.tab === 'friends') {
|
|
|
- console.log('================================================')
|
|
|
- console.log(`this.friendRecord`, this.friendRecord)
|
|
|
- console.log(`newVal`, newVal)
|
|
|
- console.log(`this.friendRecord[newVal.id]`, this.friendRecord[newVal.id])
|
|
|
- console.log(`this.friendRecord`, this.friendRecord)
|
|
|
-
|
|
|
+ if (this.tab === "friends") {
|
|
|
if (this.friendRecord[newVal.id]) {
|
|
|
this.friend_record_list = this.friendRecord[newVal.id];
|
|
|
} else {
|
|
|
- this.$store.commit('chat/set_friend_record', [newVal.id])
|
|
|
+ this.$store.commit("chat/set_friend_record", [newVal.id]);
|
|
|
this.friend_record_list = this.friendRecord[newVal.id];
|
|
|
- console.log(`this.friendRecord`, this.friendRecord)
|
|
|
+ console.log(`this.friendRecord`, this.friendRecord);
|
|
|
}
|
|
|
} else {
|
|
|
if (this.roomRecord[newVal.id]) {
|
|
|
this.room_record_list = this.roomRecord[newVal.id];
|
|
|
} else {
|
|
|
- this.$store.commit('chat/set_room_record', newVal.id)
|
|
|
+ this.$store.commit("chat/set_room_record", newVal.id);
|
|
|
this.room_record_list = this.roomRecord[newVal.id];
|
|
|
- console.log(`this.room_record_list[newVal.id]`, this.room_record_list)
|
|
|
- }
|
|
|
+ console.log(
|
|
|
+ `this.room_record_list[newVal.id]`,
|
|
|
+ this.room_record_list
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|
|
|
this.$nextTick(() => {
|
|
|
- document.getElementById('charInput').innerText = ''
|
|
|
- this.msg = ''
|
|
|
- this.$refs["myScrollbar"].wrap.scrollTop =
|
|
|
- this.$refs["myScrollbar"].wrap.scrollHeight;
|
|
|
+ document.getElementById("charInput").innerText = "";
|
|
|
+ this.msg = "";
|
|
|
+ this.$refs["myScrollbar"].wrap.scrollTop = this.$refs[
|
|
|
+ "myScrollbar"
|
|
|
+ ].wrap.scrollHeight;
|
|
|
});
|
|
|
}
|
|
|
},
|
|
@@ -415,14 +413,16 @@ export default {
|
|
|
let fd = new FormData();
|
|
|
fd.append("filename", file);
|
|
|
// upload_file(fd).then(
|
|
|
- request.upload_file(file).then(res => {
|
|
|
- console.log(`res5555`, res)
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- console.log(`err`, err)
|
|
|
- })
|
|
|
+ request
|
|
|
+ .upload_file(file)
|
|
|
+ .then(res => {
|
|
|
+ console.log(`res5555`, res);
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ console.log(`err`, err);
|
|
|
+ });
|
|
|
this.$http.post(this.baseUrl + "api/upload/", fd).then(
|
|
|
- (res) => {
|
|
|
+ res => {
|
|
|
if (
|
|
|
file.type === "image/jpeg" ||
|
|
|
file.type === "image/png" ||
|
|
@@ -430,7 +430,7 @@ export default {
|
|
|
) {
|
|
|
this.messageType = "image";
|
|
|
this.sendMsg(null, res.data.data);
|
|
|
- console.log(`res.data.data`, res.data.data)
|
|
|
+ console.log(`res.data.data`, res.data.data);
|
|
|
console.log("========is image =====");
|
|
|
} else {
|
|
|
this.messageType = "file";
|
|
@@ -440,7 +440,7 @@ export default {
|
|
|
console.log(`res1111`, res);
|
|
|
console.log("======success====");
|
|
|
},
|
|
|
- (res) => {
|
|
|
+ res => {
|
|
|
this.$message.error("文件发送失败");
|
|
|
console.log("===========shibai====");
|
|
|
// this.importDataBtnText='导入失败';
|
|
@@ -459,17 +459,20 @@ export default {
|
|
|
*/
|
|
|
_parseHtml(text) {
|
|
|
const regex2 = /!!\[(.+?)\]!!/g;
|
|
|
- const codeList = text.match(regex2)
|
|
|
- let html = text
|
|
|
+ const codeList = text.match(regex2);
|
|
|
+ let html = text;
|
|
|
if (codeList) {
|
|
|
- codeList.map((item) => {
|
|
|
- const code = item.match(/\[(.+?)\]/g)[0]
|
|
|
- html = html.replace(item, "<img style='width: 20px; height: 20px;vertical-align: sub;' src='" +
|
|
|
- this.getIconPic(code) +
|
|
|
- "' unicode = '" +
|
|
|
- code +
|
|
|
- "' alt='' >")
|
|
|
- })
|
|
|
+ codeList.map(item => {
|
|
|
+ const code = item.match(/\[(.+?)\]/g)[0];
|
|
|
+ html = html.replace(
|
|
|
+ item,
|
|
|
+ "<img style='width: 20px; height: 20px;vertical-align: sub;' src='" +
|
|
|
+ this.getIconPic(code) +
|
|
|
+ "' unicode = '" +
|
|
|
+ code +
|
|
|
+ "' alt='' >"
|
|
|
+ );
|
|
|
+ });
|
|
|
}
|
|
|
return parseHtml(html);
|
|
|
},
|
|
@@ -509,7 +512,7 @@ export default {
|
|
|
while (count < file.size) {
|
|
|
fileChunkList.push({
|
|
|
file: file.slice(count, count + size),
|
|
|
- partNumber: num,
|
|
|
+ partNumber: num
|
|
|
});
|
|
|
count += size;
|
|
|
num++;
|
|
@@ -530,13 +533,13 @@ export default {
|
|
|
width = 138;
|
|
|
return {
|
|
|
width: `${width + 12}px`,
|
|
|
- height: `${height + 12}px`,
|
|
|
+ height: `${height + 12}px`
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
return {
|
|
|
width: `${width + 12}px`,
|
|
|
- height: `${height + 12}px`,
|
|
|
+ height: `${height + 12}px`
|
|
|
};
|
|
|
},
|
|
|
|
|
@@ -593,16 +596,19 @@ export default {
|
|
|
},
|
|
|
|
|
|
// 初始化emoji的map对象
|
|
|
- initEmojiPic () {
|
|
|
- let map = new Map()
|
|
|
+ initEmojiPic() {
|
|
|
+ let map = new Map();
|
|
|
|
|
|
for (const key in emojiData.icon) {
|
|
|
emojiData.icon[key].forEach(item => {
|
|
|
- map.set(item.unicode, require('./../assets/emoji/icon/' + item.unicode + '.png'))
|
|
|
- })
|
|
|
+ map.set(
|
|
|
+ item.unicode,
|
|
|
+ require("./../assets/emoji/icon/" + item.unicode + ".png")
|
|
|
+ );
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
- this.emojiPath = map
|
|
|
+ this.emojiPath = map;
|
|
|
},
|
|
|
// 通过Unicode码从map中获取emoji
|
|
|
getIconPic(unicode) {
|
|
@@ -611,92 +617,98 @@ export default {
|
|
|
|
|
|
// ===============================================================
|
|
|
// 将输入框中的图片替换为emoji表情
|
|
|
- formatInputCon () {
|
|
|
- let inputValue = document.getElementById('charInput').innerHTML
|
|
|
+ formatInputCon() {
|
|
|
+ let inputValue = document.getElementById("charInput").innerHTML;
|
|
|
+
|
|
|
+ inputValue = inputValue.replace(/<img.*?(?:>|\/>)/gi, val => {
|
|
|
+ let unicode =
|
|
|
+ "!!" + val.match(/unicode=[\'\"]?([^\'\"]*)[\'\"]?/i)[1] + "!!";
|
|
|
|
|
|
- inputValue = inputValue.replace(/<img.*?(?:>|\/>)/gi, (val) => {
|
|
|
- let unicode = '!!' + val.match(/unicode=[\'\"]?([^\'\"]*)[\'\"]?/i)[1] + '!!'
|
|
|
-
|
|
|
- return unicode
|
|
|
- })
|
|
|
+ return unicode;
|
|
|
+ });
|
|
|
|
|
|
- return inputValue
|
|
|
+ return inputValue;
|
|
|
},
|
|
|
|
|
|
// 将emoji表情转换为图片
|
|
|
- changeEmojiCon (str) {
|
|
|
- let patt = /[\ud800-\udbff][\udc00-\udfff]/g // 检测utf16字符正则
|
|
|
+ changeEmojiCon(str) {
|
|
|
+ let patt = /[\ud800-\udbff][\udc00-\udfff]/g; // 检测utf16字符正则
|
|
|
+
|
|
|
+ str = str.replace(patt, char => {
|
|
|
+ let H, L, code;
|
|
|
|
|
|
- str = str.replace(patt, (char) => {
|
|
|
- let H, L, code
|
|
|
-
|
|
|
if (char.length === 2) {
|
|
|
- H = char.charCodeAt(0) // 取出高位
|
|
|
- L = char.charCodeAt(1) // 取出低位
|
|
|
- code = (H - 0xD800) * 0x400 + 0x10000 + L - 0xDC00 // 转换算法
|
|
|
- return "&#" + code + ";"
|
|
|
+ H = char.charCodeAt(0); // 取出高位
|
|
|
+ L = char.charCodeAt(1); // 取出低位
|
|
|
+ code = (H - 0xd800) * 0x400 + 0x10000 + L - 0xdc00; // 转换算法
|
|
|
+ return "&#" + code + ";";
|
|
|
} else {
|
|
|
- return char
|
|
|
+ return char;
|
|
|
}
|
|
|
- })
|
|
|
+ });
|
|
|
|
|
|
- str = str.replace(/&#{1}[0-9]+;{1}/ig, (a) => {
|
|
|
- let unicode = a.replace(/^&#{1}/ig, '')
|
|
|
-
|
|
|
- unicode = unicode.replace(/;{1}$/ig, '')
|
|
|
- unicode = 'U+' + (parseFloat(unicode).toString(16).toUpperCase())
|
|
|
+ str = str.replace(/&#{1}[0-9]+;{1}/gi, a => {
|
|
|
+ let unicode = a.replace(/^&#{1}/gi, "");
|
|
|
|
|
|
- return "<img src='"+ this.getIconPic(unicode) +"'/>"
|
|
|
- })
|
|
|
+ unicode = unicode.replace(/;{1}$/gi, "");
|
|
|
+ unicode =
|
|
|
+ "U+" +
|
|
|
+ parseFloat(unicode)
|
|
|
+ .toString(16)
|
|
|
+ .toUpperCase();
|
|
|
|
|
|
- return str
|
|
|
+ return "<img src='" + this.getIconPic(unicode) + "'/>";
|
|
|
+ });
|
|
|
+
|
|
|
+ return str;
|
|
|
},
|
|
|
// 延时记录光标到位置
|
|
|
- chartFramRange (type) {
|
|
|
+ chartFramRange(type) {
|
|
|
try {
|
|
|
- if (type === 'click') {
|
|
|
- this.inputRange = window.getSelection().getRangeAt(0)
|
|
|
+ if (type === "click") {
|
|
|
+ this.inputRange = window.getSelection().getRangeAt(0);
|
|
|
}
|
|
|
|
|
|
- if (type === 'focus') {
|
|
|
- this.inputRange = window.getSelection().getRangeAt(0)
|
|
|
+ if (type === "focus") {
|
|
|
+ this.inputRange = window.getSelection().getRangeAt(0);
|
|
|
}
|
|
|
} catch (err) {
|
|
|
- console.log(type)
|
|
|
+ console.log(type);
|
|
|
}
|
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
setTimeout(() => {
|
|
|
- this.inputRange = window.getSelection().getRangeAt(0)
|
|
|
- resolve(this.inputRange)
|
|
|
- }, 0)
|
|
|
- })
|
|
|
+ this.inputRange = window.getSelection().getRangeAt(0);
|
|
|
+ resolve(this.inputRange);
|
|
|
+ }, 0);
|
|
|
+ });
|
|
|
},
|
|
|
|
|
|
-
|
|
|
// 延时记录光标到位置
|
|
|
- saveRangeLocal () {
|
|
|
+ saveRangeLocal() {
|
|
|
setTimeout(() => {
|
|
|
- this.inputRange = window.getSelection().getRangeAt(0)
|
|
|
- }, 0)
|
|
|
+ this.inputRange = window.getSelection().getRangeAt(0);
|
|
|
+ }, 0);
|
|
|
},
|
|
|
// ================================================================
|
|
|
// 阻止回车键默认事件
|
|
|
stopPropagation(e) {
|
|
|
- if (e && e.keyCode === 13) {
|
|
|
+ if (e && e.keyCode === 13) {
|
|
|
e.cancelBubble = true;
|
|
|
e.preventDefault();
|
|
|
e.stopPropagation();
|
|
|
}
|
|
|
},
|
|
|
sendMsg(e, fileurl) {
|
|
|
- console.log(`e============`, e)
|
|
|
-
|
|
|
- if (fileurl) { // 上传文件路径
|
|
|
+ console.log(`e============`, e);
|
|
|
+
|
|
|
+ if (fileurl) {
|
|
|
+ // 上传文件路径
|
|
|
this.msg = fileurl;
|
|
|
- } else { // 输入框信息
|
|
|
- this.msg = this.formatInputCon().replace(/<br>/g, '\r\n')
|
|
|
- console.log(`this.msg`, this.msg)
|
|
|
+ } else {
|
|
|
+ // 输入框信息
|
|
|
+ this.msg = this.formatInputCon().replace(/<br>/g, "\r\n");
|
|
|
+ console.log(`this.msg`, this.msg);
|
|
|
}
|
|
|
if (this.msg.trim() === "") {
|
|
|
this.msg = "";
|
|
@@ -709,36 +721,35 @@ export default {
|
|
|
...this.self,
|
|
|
id: this.socket.id,
|
|
|
msg: this.msg,
|
|
|
- type: this.messageType,
|
|
|
+ type: this.messageType
|
|
|
};
|
|
|
if (this.tab === "friends") {
|
|
|
msgInfo.toid = this.selected.id;
|
|
|
this.socket.emit("private message", this.selected.id, msgInfo);
|
|
|
- const msgData = [this.selected.id, msgInfo]
|
|
|
- this.$store.commit('chat/set_friend_record', msgData)
|
|
|
+ const msgData = [this.selected.id, msgInfo];
|
|
|
+ this.$store.commit("chat/set_friend_record", msgData);
|
|
|
this.friend_record_list = this.friendRecord[this.selected.id];
|
|
|
} else {
|
|
|
- console.log('=======ROOM CHAT========')
|
|
|
+ console.log("=======ROOM CHAT========");
|
|
|
msgInfo.roomId = this.selected.id;
|
|
|
this.socket.emit("chat-room", this.selected.id, msgInfo);
|
|
|
- this.$store.commit('chat/set_room_record', msgInfo)
|
|
|
+ this.$store.commit("chat/set_room_record", msgInfo);
|
|
|
this.room_record_list = this.roomRecord[this.selected.id];
|
|
|
}
|
|
|
this.$nextTick(() => {
|
|
|
// 输入enter后置空
|
|
|
- document.getElementById('charInput').innerText = ''
|
|
|
- this.msg = "";
|
|
|
+ document.getElementById("charInput").innerText = "";
|
|
|
+ this.msg = "";
|
|
|
this.messageType = "";
|
|
|
// 滚动到底部
|
|
|
- this.$refs["myScrollbar"].wrap.scrollTop =
|
|
|
- this.$refs["myScrollbar"].wrap.scrollHeight;
|
|
|
+ this.$refs["myScrollbar"].wrap.scrollTop = this.$refs["myScrollbar"].wrap.scrollHeight;
|
|
|
});
|
|
|
},
|
|
|
|
|
|
closeScoket() {
|
|
|
// 断开连接
|
|
|
this.$socket.close();
|
|
|
- },
|
|
|
+ }
|
|
|
},
|
|
|
created() {
|
|
|
// const room_record_str = getCookie("room_record");
|
|
@@ -750,9 +761,9 @@ export default {
|
|
|
// this.friend_record = JSON.parse(friend_record_str);
|
|
|
// }
|
|
|
},
|
|
|
- mounted () {
|
|
|
- this.initEmojiPic()
|
|
|
- },
|
|
|
+ mounted() {
|
|
|
+ this.initEmojiPic();
|
|
|
+ }
|
|
|
};
|
|
|
</script>
|
|
|
|
|
@@ -831,7 +842,7 @@ export default {
|
|
|
}
|
|
|
.receive-record-item {
|
|
|
margin: 2px;
|
|
|
- background: #fff
|
|
|
+ background: #fff;
|
|
|
}
|
|
|
.input-box {
|
|
|
display: flex;
|
|
@@ -847,53 +858,51 @@ export default {
|
|
|
text-align: right;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
.chatframe_input_con {
|
|
|
- display: inline-block;
|
|
|
- width: 92%;
|
|
|
- height: 95px;
|
|
|
- resize: none;
|
|
|
- padding: 5px 15px;
|
|
|
- line-height: 1.5;
|
|
|
- box-sizing: border-box;
|
|
|
- font-size: inherit;
|
|
|
- color: #606266;
|
|
|
- background-color: #fff;
|
|
|
- outline: none;
|
|
|
- overflow-y: scroll;
|
|
|
- margin-bottom: 20px;
|
|
|
-
|
|
|
- // 超出自动换行 -- 火狐
|
|
|
- word-wrap: break-word;
|
|
|
- word-break: break-all;
|
|
|
-
|
|
|
- // 滚动样式 细 - 火狐
|
|
|
- scrollbar-width: thin;
|
|
|
-
|
|
|
- }
|
|
|
+ display: inline-block;
|
|
|
+ width: 92%;
|
|
|
+ height: 95px;
|
|
|
+ resize: none;
|
|
|
+ padding: 5px 15px;
|
|
|
+ line-height: 1.5;
|
|
|
+ box-sizing: border-box;
|
|
|
+ font-size: inherit;
|
|
|
+ color: #606266;
|
|
|
+ background-color: #fff;
|
|
|
+ outline: none;
|
|
|
+ overflow-y: scroll;
|
|
|
+ margin-bottom: 20px;
|
|
|
+
|
|
|
+ // 超出自动换行 -- 火狐
|
|
|
+ word-wrap: break-word;
|
|
|
+ word-break: break-all;
|
|
|
+
|
|
|
+ // 滚动样式 细 - 火狐
|
|
|
+ scrollbar-width: thin;
|
|
|
+}
|
|
|
|
|
|
- .chatframe-text {
|
|
|
- min-height: 200px;
|
|
|
- width: 500px;
|
|
|
- box-sizing: border-box;
|
|
|
- padding: 10px 15px;
|
|
|
- margin-top: 5px;
|
|
|
- background: #EAEDF1;
|
|
|
- color: #282828;
|
|
|
- border-radius: 4px;
|
|
|
- word-wrap: break-word;
|
|
|
- word-break: break-all;
|
|
|
- line-height: 18px;
|
|
|
- white-space: pre-wrap;
|
|
|
- position: relative;
|
|
|
- }
|
|
|
+.chatframe-text {
|
|
|
+ min-height: 200px;
|
|
|
+ width: 500px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding: 10px 15px;
|
|
|
+ margin-top: 5px;
|
|
|
+ background: #eaedf1;
|
|
|
+ color: #282828;
|
|
|
+ border-radius: 4px;
|
|
|
+ word-wrap: break-word;
|
|
|
+ word-break: break-all;
|
|
|
+ line-height: 18px;
|
|
|
+ white-space: pre-wrap;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
|
|
|
- .text_emoji {
|
|
|
- img {
|
|
|
- display:inline-block;
|
|
|
- width: 20px;
|
|
|
- height: 20px;
|
|
|
- vertical-align: bottom;
|
|
|
- }
|
|
|
+.text_emoji {
|
|
|
+ img {
|
|
|
+ display: inline-block;
|
|
|
+ width: 20px;
|
|
|
+ height: 20px;
|
|
|
+ vertical-align: bottom;
|
|
|
}
|
|
|
+}
|
|
|
</style>
|