mirror of
https://github.com/kuaifan/dootask.git
synced 2026-02-28 12:50:48 +00:00
perf: 优化搜索表情
This commit is contained in:
parent
c2d852eb3a
commit
963474f32e
@ -338,30 +338,6 @@ class IndexController extends InvokeController
|
||||
return abort(404);
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索表情
|
||||
* @return array
|
||||
*/
|
||||
public function emo__search()
|
||||
{
|
||||
$key = Request::input('key');
|
||||
if (empty($key)) {
|
||||
return Base::retError("key empty");
|
||||
}
|
||||
return Cache::remember("emo__search:" . md5($key), now()->addDay(), function () use ($key) {
|
||||
$res = Ihttp::ihttp_get("http://www.adoutu.com/search?keyword=" . urlencode($key));
|
||||
if (Base::isError($res)) {
|
||||
return $res;
|
||||
}
|
||||
$content = Base::getMiddle($res['data'], '<!--图片列表-->', '<!--分页器-->');
|
||||
preg_match_all("/<img\s+src=\"(.*?)\"/s", $content, $matchs);
|
||||
if ($matchs && $matchs[1]) {
|
||||
return Base::retSuccess('success', array_slice($matchs[1], 0, 20));
|
||||
}
|
||||
return Base::retError("result empty");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置语言和皮肤
|
||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
|
||||
|
||||
@ -537,7 +537,7 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
{
|
||||
if (!$text) return '';
|
||||
$text = preg_replace("/<img\s+class=\"emoticon\"[^>]*?alt=\"(\S+)\"[^>]*?>/", "[$1]", $text);
|
||||
$text = preg_replace("/<img\s+class=\"emoticon\"[^>]*?>/", "[表情]", $text);
|
||||
$text = preg_replace("/<img\s+class=\"emoticon\"[^>]*?>/", "[动画表情]", $text);
|
||||
$text = preg_replace("/<img\s+class=\"browse\"[^>]*?>/", "[图片]", $text);
|
||||
if (!$preserveHtml) {
|
||||
$text = strip_tags($text);
|
||||
@ -558,15 +558,15 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
// 图片 [:IMAGE:className:width:height:src:alt:]
|
||||
preg_match_all("/<img\s+src=\"data:image\/(png|jpg|jpeg|gif);base64,(.*?)\"(.*?)>(<\/img>)*/s", $text, $matchs);
|
||||
foreach ($matchs[2] as $key => $base64) {
|
||||
$tmpPath = "uploads/chat/" . date("Ym") . "/" . $dialog_id . "/";
|
||||
Base::makeDir(public_path($tmpPath));
|
||||
$tmpPath .= md5s($base64) . "." . $matchs[1][$key];
|
||||
if (file_put_contents(public_path($tmpPath), base64_decode($base64))) {
|
||||
$imagesize = getimagesize(public_path($tmpPath));
|
||||
if (Base::imgThumb(public_path($tmpPath), public_path($tmpPath) . "_thumb.jpg", 320, 0)) {
|
||||
$tmpPath .= "_thumb.jpg";
|
||||
$imagePath = "uploads/chat/" . date("Ym") . "/" . $dialog_id . "/";
|
||||
Base::makeDir(public_path($imagePath));
|
||||
$imagePath .= md5s($base64) . "." . $matchs[1][$key];
|
||||
if (file_put_contents(public_path($imagePath), base64_decode($base64))) {
|
||||
$imageSize = getimagesize(public_path($imagePath));
|
||||
if (Base::imgThumb(public_path($imagePath), public_path($imagePath) . "_thumb.jpg", 320, 0)) {
|
||||
$imagePath .= "_thumb.jpg";
|
||||
}
|
||||
$text = str_replace($matchs[0][$key], "[:IMAGE:browse:{$imagesize[0]}:{$imagesize[1]}:{$tmpPath}::]", $text);
|
||||
$text = str_replace($matchs[0][$key], "[:IMAGE:browse:{$imageSize[0]}:{$imageSize[1]}:{$imagePath}::]", $text);
|
||||
}
|
||||
}
|
||||
// 表情图片
|
||||
@ -574,38 +574,73 @@ class WebSocketDialogMsg extends AbstractModel
|
||||
foreach ($matchs[1] as $key => $str) {
|
||||
preg_match("/data-asset=\"(.*?)\"/", $str, $matchAsset);
|
||||
preg_match("/data-name=\"(.*?)\"/", $str, $matchName);
|
||||
if (file_exists(public_path($matchAsset[1]))) {
|
||||
$imagesize = getimagesize(public_path($matchAsset[1]));
|
||||
$text = str_replace($matchs[0][$key], "[:IMAGE:emoticon:{$imagesize[0]}:{$imagesize[1]}:{$matchAsset[1]}:{$matchName[1]}:]", $text);
|
||||
$imageSize = null;
|
||||
$imagePath = "";
|
||||
$imageName = "";
|
||||
if ($matchAsset[1] === "emosearch") {
|
||||
preg_match("/src=\"(.*?)\"/", $str, $matchSrc);
|
||||
if ($matchSrc) {
|
||||
$srcMd5 = md5($matchSrc[1]);
|
||||
$imagePath = "uploads/emosearch/" . substr($srcMd5, 0, 2) . "/" . substr($srcMd5, 32 - 2) . "/";
|
||||
Base::makeDir(public_path($imagePath));
|
||||
$imagePath .= md5s($matchSrc[1]);
|
||||
if (file_exists(public_path($imagePath))) {
|
||||
$imageSize = getimagesize(public_path($imagePath));
|
||||
} else {
|
||||
$image = file_get_contents($matchSrc[1]);
|
||||
if ($image && file_put_contents(public_path($imagePath), $image)) {
|
||||
$imageSize = getimagesize(public_path($imagePath));
|
||||
// 添加后缀
|
||||
if ($imageSize && !str_contains($imagePath, '.')) {
|
||||
preg_match("/^image\/(png|jpg|jpeg|gif)$/", $imageSize['mime'], $matchMine);
|
||||
if ($matchMine) {
|
||||
$imageNewPath = $imagePath . "." . $matchMine[1];
|
||||
if (rename(public_path($imagePath), public_path($imageNewPath))) {
|
||||
$imagePath = $imageNewPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} elseif (file_exists(public_path($matchAsset[1]))) {
|
||||
$imagePath = $matchAsset[1];
|
||||
$imageName = $matchName[1];
|
||||
$imageSize = getimagesize(public_path($matchAsset[1]));
|
||||
}
|
||||
if ($imageSize) {
|
||||
$text = str_replace($matchs[0][$key], "[:IMAGE:emoticon:{$imageSize[0]}:{$imageSize[1]}:{$imagePath}:{$imageName}:]", $text);
|
||||
} else {
|
||||
$text = str_replace($matchs[0][$key], "[:IMAGE:browse:90:90:images/other/imgerr.jpg::]", $text);
|
||||
}
|
||||
}
|
||||
// 其他网络图片
|
||||
preg_match_all("/<img[^>]*?src=([\"'])(.*?\.(png|jpg|jpeg|gif))\\1[^>]*?>/is", $text, $matchs);
|
||||
foreach ($matchs[2] as $key => $str) {
|
||||
if (str_starts_with($str, "{{RemoteURL}}")) {
|
||||
$tmpPath = Base::leftDelete($str, "{{RemoteURL}}");
|
||||
$tmpPath = Base::rightDelete($tmpPath, "_thumb.jpg");
|
||||
$imagePath = Base::leftDelete($str, "{{RemoteURL}}");
|
||||
$imagePath = Base::rightDelete($imagePath, "_thumb.jpg");
|
||||
} else {
|
||||
$tmpPath = "uploads/chat/" . date("Ym") . "/" . $dialog_id . "/";
|
||||
Base::makeDir(public_path($tmpPath));
|
||||
$tmpPath .= md5s($str) . "." . $matchs[3][$key];
|
||||
$imagePath = "uploads/chat/" . date("Ym") . "/" . $dialog_id . "/";
|
||||
Base::makeDir(public_path($imagePath));
|
||||
$imagePath .= md5s($str) . "." . $matchs[3][$key];
|
||||
}
|
||||
if (file_exists(public_path($tmpPath))) {
|
||||
$imagesize = getimagesize(public_path($tmpPath));
|
||||
if (Base::imgThumb(public_path($tmpPath), public_path($tmpPath) . "_thumb.jpg", 320, 0)) {
|
||||
$tmpPath .= "_thumb.jpg";
|
||||
if (file_exists(public_path($imagePath))) {
|
||||
$imageSize = getimagesize(public_path($imagePath));
|
||||
if (Base::imgThumb(public_path($imagePath), public_path($imagePath) . "_thumb.jpg", 320, 0)) {
|
||||
$imagePath .= "_thumb.jpg";
|
||||
}
|
||||
$text = str_replace($matchs[0][$key], "[:IMAGE:browse:{$imagesize[0]}:{$imagesize[1]}:{$tmpPath}::]", $text);
|
||||
$text = str_replace($matchs[0][$key], "[:IMAGE:browse:{$imageSize[0]}:{$imageSize[1]}:{$imagePath}::]", $text);
|
||||
} else {
|
||||
$image = file_get_contents($str);
|
||||
if (empty($image)) {
|
||||
$text = str_replace($matchs[0][$key], "[:IMAGE:browse:90:90:images/other/imgerr.jpg::]", $text);
|
||||
} else if (file_put_contents(public_path($tmpPath), $image)) {
|
||||
$imagesize = getimagesize(public_path($tmpPath));
|
||||
if (Base::imgThumb(public_path($tmpPath), public_path($tmpPath) . "_thumb.jpg", 320, 0)) {
|
||||
$tmpPath .= "_thumb.jpg";
|
||||
} else if (file_put_contents(public_path($imagePath), $image)) {
|
||||
$imageSize = getimagesize(public_path($imagePath));
|
||||
if (Base::imgThumb(public_path($imagePath), public_path($imagePath) . "_thumb.jpg", 320, 0)) {
|
||||
$imagePath .= "_thumb.jpg";
|
||||
}
|
||||
$text = str_replace($matchs[0][$key], "[:IMAGE:browse:{$imagesize[0]}:{$imagesize[1]}:{$tmpPath}::]", $text);
|
||||
$text = str_replace($matchs[0][$key], "[:IMAGE:browse:{$imageSize[0]}:{$imageSize[1]}:{$imagePath}::]", $text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@
|
||||
"vue-clipboard2": "^0.3.3",
|
||||
"vue-kityminder-ggg": "^1.3.10",
|
||||
"vue-loader": "^15.9.8",
|
||||
"vue-jsonp": "^2.0.0",
|
||||
"vue-resize-observer": "^2.0.16",
|
||||
"vue-router": "^3.5.3",
|
||||
"vue-template-compiler": "^2.6.14",
|
||||
|
||||
2
resources/assets/js/functions/web.js
vendored
2
resources/assets/js/functions/web.js
vendored
@ -373,7 +373,7 @@
|
||||
getMsgTextPreview(text) {
|
||||
if (!text) return '';
|
||||
text = text.replace(/<img\s+class="emoticon"[^>]*?alt="(\S+)"[^>]*?>/g, "[$1]")
|
||||
text = text.replace(/<img\s+class="emoticon"[^>]*?>/g, `[${$A.L('表情')}]`)
|
||||
text = text.replace(/<img\s+class="emoticon"[^>]*?>/g, `[${$A.L('动画表情')}]`)
|
||||
text = text.replace(/<img\s+class="browse"[^>]*?>/g, `[${$A.L('图片')}]`)
|
||||
text = text.replace(/ /g," ")
|
||||
return text.replace(/<[^>]+>/g,"")
|
||||
|
||||
@ -1,15 +1,25 @@
|
||||
<template>
|
||||
<div class="chat-emoji-wrapper">
|
||||
<ul class="chat-emoji-box scrollbar-overlay" :class="[type, 'no-dark-content']">
|
||||
<li v-for="item in list" @click="onSelect(item)">
|
||||
<img v-if="item.type === 'emoticon'" :src="item.src" :title="item.name" :alt="item.name"/>
|
||||
<span v-else v-html="item.html" :title="item.name"></span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="chat-emoji-box">
|
||||
<div v-if="type === 'emosearch'" class="chat-emoji-emosearch">
|
||||
<Input clearable v-model="emosearchKey" :placeholder="$L('搜索表情')">
|
||||
<Icon :type="emosearchLoad ? 'ios-loading' : 'ios-search'" :class="{'icon-loading': emosearchLoad}" slot="prefix" />
|
||||
</Input>
|
||||
</div>
|
||||
<ul class="scrollbar-overlay" :class="[type, 'no-dark-content']">
|
||||
<li v-for="item in list" @click="onSelect(item)">
|
||||
<img v-if="item.type === 'emoticon'" :src="item.src" :title="item.name" :alt="item.name"/>
|
||||
<span v-else v-html="item.html" :title="item.name"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="chat-emoji-menu">
|
||||
<li :class="{active: type === 'emoji'}" @click="type='emoji'">
|
||||
<span class="no-dark-content">😀</span>
|
||||
</li>
|
||||
<li :class="{active: type === 'emosearch'}" @click="type='emosearch'">
|
||||
<i class="taskfont"></i>
|
||||
</li>
|
||||
<li v-for="item in emoticonList" :class="{active: type === 'emoticon' && emoticonPath == item.path}" @click="onEmoticon(item.path)">
|
||||
<img :title="item.name" :alt="item.name" :src="item.src"/>
|
||||
</li>
|
||||
@ -18,20 +28,40 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { jsonp } from 'vue-jsonp'
|
||||
|
||||
export default {
|
||||
name: 'ChatEmoji',
|
||||
props: {
|
||||
|
||||
searchKey: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
type: 'emoji',
|
||||
emoticonPath: '',
|
||||
|
||||
emosearchKey: '',
|
||||
emosearchCache: null,
|
||||
emosearchLoad: false,
|
||||
emosearchTimer: null,
|
||||
emosearchList: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
||||
if (this.searchKey) {
|
||||
this.emosearchKey = this.searchKey;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
type() {
|
||||
this.onEmosearch()
|
||||
},
|
||||
emosearchKey() {
|
||||
this.onEmosearch()
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
list() {
|
||||
@ -48,6 +78,8 @@ export default {
|
||||
html: item.code_decimal,
|
||||
}
|
||||
})
|
||||
} else if (this.type === 'emosearch') {
|
||||
return this.emosearchList;
|
||||
} else if (this.type === 'emoticon') {
|
||||
const data = this.emoticonList.find(({path}) => path === this.emoticonPath)
|
||||
if (data) {
|
||||
@ -56,6 +88,7 @@ export default {
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
emoticonList() {
|
||||
if ($A.isArray(window.emoticonData)) {
|
||||
let baseUrl = $A.apiUrl("../images/emoticon")
|
||||
@ -76,6 +109,46 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onEmosearch() {
|
||||
if (this.type !== 'emosearch' || this.emosearchCache === this.emosearchKey) {
|
||||
return
|
||||
}
|
||||
this.emosearchCache = this.emosearchKey;
|
||||
//
|
||||
this.emosearchLoad = true;
|
||||
this.emosearchTimer && clearTimeout(this.emosearchTimer)
|
||||
this.emosearchTimer = setTimeout(_ => {
|
||||
jsonp('https://pic.sogou.com/napi/wap/pic', {
|
||||
query: this.emosearchKey + ' 表情'
|
||||
}).then(data => {
|
||||
this.emosearchList = []
|
||||
if (data.status === 0) {
|
||||
const items = data.data.items
|
||||
if (items.length > 0) {
|
||||
this.emosearchList = items.map(item => {
|
||||
return {
|
||||
type: 'emoticon',
|
||||
asset: 'emosearch',
|
||||
name: item.title,
|
||||
src: item.thumbUrl,
|
||||
height: item.thumbHeight,
|
||||
width: item.thumbWidth,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
if (this.emosearchList.length === 0) {
|
||||
$A.noticeWarning("没有搜索到任何表情")
|
||||
}
|
||||
}).catch(_ => {
|
||||
this.emosearchList = []
|
||||
$A.noticeWarning("搜索结果为空")
|
||||
}).finally(_ => {
|
||||
this.emosearchLoad = false;
|
||||
})
|
||||
}, 300)
|
||||
},
|
||||
|
||||
onEmoticon(path) {
|
||||
this.type = 'emoticon';
|
||||
this.emoticonPath = path;
|
||||
|
||||
@ -47,7 +47,7 @@
|
||||
<ETooltip slot="reference" ref="emojiTip" :disabled="windowSmall || showEmoji" placement="top" :content="$L('表情')">
|
||||
<i class="taskfont"></i>
|
||||
</ETooltip>
|
||||
<ChatEmoji @on-select="onSelectEmoji"/>
|
||||
<ChatEmoji v-if="showEmoji" @on-select="onSelectEmoji" :searchKey="emojiQuickKey"/>
|
||||
</EPopover>
|
||||
<ETooltip v-else ref="emojiTip" :disabled="windowSmall || showEmoji" placement="top" :content="$L('表情')">
|
||||
<i class="taskfont" @click="showEmoji=!showEmoji"></i>
|
||||
@ -125,7 +125,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 移动端表情(底部) -->
|
||||
<ChatEmoji v-if="emojiBottom && showEmoji" @on-select="onSelectEmoji"/>
|
||||
<ChatEmoji v-if="emojiBottom && showEmoji" @on-select="onSelectEmoji" :searchKey="emojiQuickKey"/>
|
||||
|
||||
<!-- 录音浮窗 -->
|
||||
<transition name="fade">
|
||||
@ -230,6 +230,7 @@ export default {
|
||||
showEmoji: false,
|
||||
emojiQuickTimer: null,
|
||||
emojiQuickShow: false,
|
||||
emojiQuickKey: '',
|
||||
emojiQuickItems: [],
|
||||
|
||||
observer: null,
|
||||
@ -710,20 +711,19 @@ export default {
|
||||
&& text.length >= 1
|
||||
&& text.length <= 4
|
||||
&& $A.isArray(window.emoticonData)) {
|
||||
// 搜索在线表情
|
||||
this.searchEmoji(text);
|
||||
// 显示快捷选择表情窗口
|
||||
this.emojiQuickKey = text;
|
||||
this.emojiQuickItems = [];
|
||||
let baseUrl = $A.apiUrl("../images/emoticon")
|
||||
window.emoticonData.some(data => {
|
||||
let item = data.list.find(({name}) => $A.strExists(name, text))
|
||||
let item = data.list.find(d => $A.strExists(d.name + (d.key ? ` ${d.key}` : ''), text))
|
||||
if (item) {
|
||||
this.emojiQuickItems.push(Object.assign(item, {
|
||||
type: `emoticon`,
|
||||
asset: `images/emoticon/${data.path}/${item.path}`,
|
||||
src: `${baseUrl}/${data.path}/${item.path}`
|
||||
}))
|
||||
if (this.emojiQuickItems.length >= 2) {
|
||||
if (this.emojiQuickItems.length >= 3) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -740,65 +740,6 @@ export default {
|
||||
}, 100)
|
||||
},
|
||||
|
||||
searchEmoji(text) {
|
||||
this.emojiSearchKey = text;
|
||||
this.emojiSearchTimer && clearTimeout(this.emojiSearchTimer);
|
||||
this.emojiSearchTimer = setTimeout(_ => {
|
||||
if (this.emojiSearchKey !== text) {
|
||||
return;
|
||||
}
|
||||
this.$store.dispatch("call", {
|
||||
url: '../emo/search',
|
||||
data: {
|
||||
key: text,
|
||||
},
|
||||
checkNetwork: false,
|
||||
}).then(({data}) => {
|
||||
if (this.emojiSearchKey !== text) {
|
||||
return;
|
||||
}
|
||||
const array = this.getRandomArrayElements(data.map(item => {
|
||||
return {
|
||||
type: "online",
|
||||
name: this.$L("动画表情"),
|
||||
src: this.asciiConvertNative(item)
|
||||
}
|
||||
}), 3 - this.emojiQuickItems.length)
|
||||
if (array.length > 0) {
|
||||
this.emojiQuickItems.push(...array)
|
||||
this.$nextTick(_ => {
|
||||
this.emojiQuickShow = true
|
||||
this.$refs.emojiQuickRef.updatePopper()
|
||||
})
|
||||
}
|
||||
});
|
||||
}, 800)
|
||||
},
|
||||
|
||||
asciiConvertNative(val) {
|
||||
let asciicode = val.split("\\u");
|
||||
let nativeValue = asciicode[0];
|
||||
for (let i = 1; i < asciicode.length; i++) {
|
||||
let code = asciicode[i];
|
||||
nativeValue += String.fromCharCode(parseInt("0x" + code.substring(0, 4)));
|
||||
if (code.length > 4) {
|
||||
nativeValue += code.substring(4, code.length);
|
||||
}
|
||||
}
|
||||
return nativeValue
|
||||
},
|
||||
|
||||
getRandomArrayElements(arr, count) {
|
||||
let shuffled = arr.slice(0), i = arr.length, min = i - count, temp, index;
|
||||
while (i-- > min) {
|
||||
index = Math.floor((i + 1) * Math.random());
|
||||
temp = shuffled[index];
|
||||
shuffled[index] = shuffled[i];
|
||||
shuffled[i] = temp;
|
||||
}
|
||||
return shuffled.slice(min);
|
||||
},
|
||||
|
||||
setText(value) {
|
||||
if (this.quill) {
|
||||
this.quill.setText(value)
|
||||
|
||||
36
resources/assets/js/store/actions.js
vendored
36
resources/assets/js/store/actions.js
vendored
@ -2159,28 +2159,26 @@ export default {
|
||||
} else {
|
||||
state.dialogIns.push(data);
|
||||
}
|
||||
// 会话消息总数量大于200时只保留最近打开的5个会话
|
||||
const msg_max = 200
|
||||
// 会话消息总数量大于100时只保留最近打开的5个会话
|
||||
const msg_max = 100
|
||||
const retain_num = 5
|
||||
if (state.dialogMsgs.length > msg_max) {
|
||||
state.dialogHistory = state.dialogHistory.filter(id => id != data.dialog_id)
|
||||
state.dialogHistory.push(data.dialog_id)
|
||||
if (state.dialogHistory.length > retain_num) {
|
||||
const historys = state.dialogHistory.slice().reverse()
|
||||
const newIds = []
|
||||
const delIds = []
|
||||
historys.forEach(id => {
|
||||
if (newIds.length < retain_num || state.dialogIns.findIndex(item => item.dialog_id == id) > -1) {
|
||||
newIds.push(id)
|
||||
} else {
|
||||
delIds.push(id)
|
||||
}
|
||||
})
|
||||
if (delIds.length > 0) {
|
||||
state.dialogMsgs = state.dialogMsgs.filter(item => !delIds.includes(item.dialog_id));
|
||||
state.dialogHistory = state.dialogHistory.filter(id => id != data.dialog_id)
|
||||
state.dialogHistory.push(data.dialog_id)
|
||||
if (state.dialogMsgs.length > msg_max && state.dialogHistory.length > retain_num) {
|
||||
const historys = state.dialogHistory.slice().reverse()
|
||||
const newIds = []
|
||||
const delIds = []
|
||||
historys.forEach(id => {
|
||||
if (newIds.length < retain_num || state.dialogIns.findIndex(item => item.dialog_id == id) > -1) {
|
||||
newIds.push(id)
|
||||
} else {
|
||||
delIds.push(id)
|
||||
}
|
||||
state.dialogHistory = newIds
|
||||
})
|
||||
if (delIds.length > 0) {
|
||||
state.dialogMsgs = state.dialogMsgs.filter(item => !delIds.includes(item.dialog_id));
|
||||
}
|
||||
state.dialogHistory = newIds
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -291,16 +291,22 @@
|
||||
|
||||
.chat-emoji-wrapper {
|
||||
.chat-emoji-box {
|
||||
width: auto;
|
||||
padding: 8px 2px;
|
||||
&::after {
|
||||
content: "";
|
||||
flex: auto;
|
||||
}
|
||||
> li {
|
||||
transition: none;
|
||||
&:hover {
|
||||
transform: none;
|
||||
> ul {
|
||||
width: auto;
|
||||
padding: 8px 2px;
|
||||
&::after {
|
||||
content: "";
|
||||
flex: auto;
|
||||
}
|
||||
> li {
|
||||
> img {
|
||||
transition: none;
|
||||
}
|
||||
&:hover {
|
||||
> img {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -325,7 +331,8 @@
|
||||
z-index: 1;
|
||||
}
|
||||
> span,
|
||||
> img {
|
||||
> img,
|
||||
> i {
|
||||
position: static;
|
||||
z-index: 2;
|
||||
}
|
||||
@ -344,46 +351,60 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.chat-emoji-emosearch {
|
||||
flex-shrink: 0;
|
||||
padding: 8px 8px 0;
|
||||
}
|
||||
|
||||
.chat-emoji-box {
|
||||
width: 360px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 280px;
|
||||
display: grid;
|
||||
justify-content: space-between;
|
||||
grid-template-columns: repeat(auto-fill, 40px);
|
||||
padding: 8px;
|
||||
flex-wrap: wrap;
|
||||
overflow-x: hidden;
|
||||
word-break: break-all;
|
||||
box-sizing: content-box;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
> ul {
|
||||
flex: 1;
|
||||
width: 360px;
|
||||
height: 0;
|
||||
display: grid;
|
||||
justify-content: space-between;
|
||||
grid-template-columns: repeat(auto-fill, 40px);
|
||||
padding: 8px;
|
||||
flex-wrap: wrap;
|
||||
overflow-x: hidden;
|
||||
word-break: break-all;
|
||||
box-sizing: content-box;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
|
||||
> li {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 22px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: transform 0.3s;
|
||||
> img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
pointer-events: none;
|
||||
-webkit-touch-callout: none;
|
||||
}
|
||||
&:hover {
|
||||
transform: scale(1.4);
|
||||
}
|
||||
}
|
||||
|
||||
&.emoticon {
|
||||
grid-template-columns: repeat(auto-fill, 72px);
|
||||
> li {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
padding: 8px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 22px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
> img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
pointer-events: none;
|
||||
-webkit-touch-callout: none;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
&:hover {
|
||||
> img {
|
||||
transform: scale(1.4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.emosearch,
|
||||
&.emoticon {
|
||||
grid-template-columns: repeat(auto-fill, 72px);
|
||||
> li {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -416,6 +437,12 @@
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
> i {
|
||||
width: 48px;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
> img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
@ -687,19 +714,22 @@
|
||||
background-color: #ffffff;
|
||||
.chat-emoji-box {
|
||||
height: 246px;
|
||||
grid-template-columns: repeat(auto-fill, 50px);
|
||||
> li {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
font-size: 28px;
|
||||
}
|
||||
&.emoticon {
|
||||
grid-template-columns: repeat(auto-fill, 80px);
|
||||
> ul {
|
||||
grid-template-columns: repeat(auto-fill, 50px);
|
||||
> li {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
padding: 8px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
font-size: 28px;
|
||||
}
|
||||
&.emosearch,
|
||||
&.emoticon {
|
||||
grid-template-columns: repeat(auto-fill, 80px);
|
||||
> li {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,16 +9,16 @@
|
||||
{name: '撸串去', path: '02.gif'},
|
||||
{name: '来喝酒', path: '03.gif'},
|
||||
{name: '走啦', path: '04.gif'},
|
||||
{name: '蟹蟹', path: '05.gif'},
|
||||
{name: '蟹蟹', key: '谢谢', path: '05.gif'},
|
||||
{name: '加个好友呗', path: '06.gif'},
|
||||
{name: '醉了', path: '07.gif'},
|
||||
{name: '哈喽', path: '08.gif'},
|
||||
{name: '哈喽', key: '你好', path: '08.gif'},
|
||||
{name: '呼叫呼叫', path: '09.gif'},
|
||||
{name: '收到over', path: '10.gif'},
|
||||
{name: '呕', path: '11.gif'},
|
||||
{name: '来嘛', path: '12.gif'},
|
||||
{name: '借酒消愁', path: '13.gif'},
|
||||
{name: '你还太年轻', path: '14.gif'},
|
||||
{name: '借酒消愁', key: '烦', path: '13.gif'},
|
||||
{name: '你还太年轻', key: '小样', path: '14.gif'},
|
||||
{name: '来 再战', path: '15.gif'},
|
||||
{name: '醒醒', path: '16.gif'},
|
||||
{name: '请你吃饭', path: '17.gif'},
|
||||
@ -27,7 +27,7 @@
|
||||
{name: '好的', path: '20.gif'},
|
||||
{name: '你又迟到了', path: '21.gif'},
|
||||
{name: '自罚一杯', path: '22.gif'},
|
||||
{name: '哈哈哈', path: '23.gif'},
|
||||
{name: '哈哈', path: '23.gif'},
|
||||
{name: '少喝点酒', path: '24.gif'},
|
||||
]
|
||||
},
|
||||
@ -36,20 +36,20 @@
|
||||
path: '02',
|
||||
icon: 'icon.png',
|
||||
list: [
|
||||
{name: '爱老虎油', path: '01.gif'},
|
||||
{name: '爱老虎油', key: '爱你', path: '01.gif'},
|
||||
{name: '比心', path: '02.gif'},
|
||||
{name: '呐,送你花花', path: '03.gif'},
|
||||
{name: '赞', path: '04.gif'},
|
||||
{name: '赞', key: '真棒 牛逼', path: '04.gif'},
|
||||
{name: '买买买', path: '05.gif'},
|
||||
{name: '饥饿', path: '06.gif'},
|
||||
{name: '问号', path: '07.gif'},
|
||||
{name: '围观', path: '08.gif'},
|
||||
{name: '哈哈哈哈哈', path: '09.gif'},
|
||||
{name: '哈哈', path: '09.gif'},
|
||||
{name: '加一', path: '10.gif'},
|
||||
{name: '嗯嗯', path: '11.gif'},
|
||||
{name: '暗中观察', path: '12.gif'},
|
||||
{name: '生日快乐', path: '13.gif'},
|
||||
{name: '蟹蟹', path: '14.gif'},
|
||||
{name: '蟹蟹', key: '谢谢', path: '14.gif'},
|
||||
{name: '加油', path: '15.gif'},
|
||||
{name: '突然吃瓜', path: '16.gif'},
|
||||
{name: '抱抱', path: '17.gif'},
|
||||
@ -79,10 +79,10 @@
|
||||
{name: '开始摆烂', path: '11.gif'},
|
||||
{name: '震惊', path: '12.gif'},
|
||||
{name: '收到', path: '13.gif'},
|
||||
{name: '赞', path: '14.gif'},
|
||||
{name: '赞', key: '真棒 牛逼', path: '14.gif'},
|
||||
{name: '心花怒放', path: '15.gif'},
|
||||
{name: '无聊', path: '16.gif'},
|
||||
{name: 'NONONO', path: '17.gif'},
|
||||
{name: 'NONONO', key: '不要 不好', path: '17.gif'},
|
||||
{name: '扎心了', path: '18.gif'},
|
||||
{name: '哼', path: '19.gif'},
|
||||
{name: '晚安', path: '20.gif'},
|
||||
@ -113,7 +113,7 @@
|
||||
{name: '打卡', path: '18.gif'},
|
||||
{name: '摇摆', path: '19.gif'},
|
||||
{name: '脑瓜嗡嗡', path: '20.gif'},
|
||||
{name: 'yes sir', path: '21.gif'},
|
||||
{name: 'yes sir', key: '是的', path: '21.gif'},
|
||||
{name: '不开心', path: '22.gif'},
|
||||
{name: '对', path: '23.gif'},
|
||||
{name: '比猪', path: '24.gif'},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user