mirror of
https://github.com/kuaifan/dootask.git
synced 2026-02-10 08:25:34 +00:00
perf: 优化长按操作
This commit is contained in:
parent
bfdb72dd0a
commit
3cb9fff07f
2
resources/assets/js/directives/longpress.js
vendored
2
resources/assets/js/directives/longpress.js
vendored
@ -7,7 +7,7 @@ const longpress = {
|
||||
mode = 'default',
|
||||
isCall = false,
|
||||
pressTimer = null,
|
||||
callback = binding.value;
|
||||
callback = binding.value; // 回调函数:第一个参数是事件对象(点到的对象),第二个参数是元素对象(注册绑定的对象)
|
||||
if ($A.isJson(binding.value)) {
|
||||
delay = binding.value.delay || 500;
|
||||
callback = binding.value.callback;
|
||||
|
||||
@ -29,12 +29,12 @@
|
||||
{{source.msg.source === 'api' ? source.msg.notice : $L(source.msg.notice)}}
|
||||
</div>
|
||||
<template v-else>
|
||||
<div class="dialog-avatar">
|
||||
<UserAvatar
|
||||
v-longpress="{callback: onMention, delay: 300}"
|
||||
@open-dialog="onOpenDialog"
|
||||
:userid="source.userid"
|
||||
:size="30"/>
|
||||
<div
|
||||
ref="avatar"
|
||||
class="dialog-avatar"
|
||||
@contextmenu="handleOperation"
|
||||
@touchstart="handleOperation">
|
||||
<UserAvatar :userid="source.userid" :size="30" @open-dialog="onOpenDialog"/>
|
||||
</div>
|
||||
<DialogView
|
||||
:msg-data="source"
|
||||
@ -46,7 +46,6 @@
|
||||
:operate-action="operateVisible && source.id === operateItem.id"
|
||||
:pointer-mouse="pointerMouse"
|
||||
:is-right-msg="isRightMsg"
|
||||
@on-longpress="onLongpress"
|
||||
@on-view-reply="onViewReply"
|
||||
@on-view-text="onViewText"
|
||||
@on-view-file="onViewFile"
|
||||
@ -63,12 +62,10 @@
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
import DialogView from "./DialogView";
|
||||
import longpress from "../../../directives/longpress";
|
||||
|
||||
export default {
|
||||
name: "DialogItem",
|
||||
components: {DialogView},
|
||||
directives: {longpress},
|
||||
props: {
|
||||
source: {
|
||||
type: Object,
|
||||
@ -217,6 +214,14 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
handleOperation() {
|
||||
this.$store.commit("longpress/set", {
|
||||
type: 'mention',
|
||||
data: this.source,
|
||||
element: this.$refs.avatar
|
||||
})
|
||||
},
|
||||
|
||||
onOpenDialog(userid) {
|
||||
if (this.dialogData.type == 'group' || ![this.dialogData.dialog_user?.userid, this.userId].includes(userid)) {
|
||||
this.$store.dispatch("openDialogUserid", userid).catch(({msg}) => {
|
||||
@ -225,14 +230,6 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
onMention() {
|
||||
this.dispatch("on-mention", this.source)
|
||||
},
|
||||
|
||||
onLongpress(e) {
|
||||
this.dispatch("on-longpress", e)
|
||||
},
|
||||
|
||||
onViewReply(data) {
|
||||
this.dispatch("on-view-reply", data)
|
||||
},
|
||||
|
||||
@ -6,10 +6,12 @@
|
||||
</div>
|
||||
|
||||
<div
|
||||
ref="dialogHead"
|
||||
class="dialog-head"
|
||||
:class="headClass"
|
||||
@click="handleClick"
|
||||
v-longpress="{callback: handleLongpress, delay: 300}">
|
||||
@contextmenu="handleOperation"
|
||||
@touchstart="handleOperation">
|
||||
<!--回复-->
|
||||
<div v-if="!hideReply && msgData.reply_id && showReplyData(msgData.msg.reply_data)" class="dialog-reply no-dark-content" :class="replyClass" @click="viewReply">
|
||||
<div class="reply-avatar">
|
||||
@ -178,7 +180,6 @@
|
||||
<script>
|
||||
import WCircle from "../../../../components/WCircle";
|
||||
import {mapGetters, mapState} from "vuex";
|
||||
import longpress from "../../../../directives/longpress";
|
||||
|
||||
import TextMsg from "./text.vue";
|
||||
import LongTextMsg from "./longtext.vue";
|
||||
@ -209,7 +210,6 @@ export default {
|
||||
FileMsg,
|
||||
WCircle
|
||||
},
|
||||
directives: {longpress},
|
||||
props: {
|
||||
msgData: {
|
||||
type: Object,
|
||||
@ -394,8 +394,12 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleLongpress(event, el) {
|
||||
this.$emit("on-longpress", {event, el, msgData: this.msgData})
|
||||
handleOperation() {
|
||||
this.$store.commit("longpress/set", {
|
||||
type: 'operateMsg',
|
||||
data: this.msgData,
|
||||
element: this.$refs.dialogHead
|
||||
})
|
||||
},
|
||||
|
||||
handleClick() {
|
||||
|
||||
@ -182,7 +182,10 @@
|
||||
</div>
|
||||
|
||||
<!--消息部分-->
|
||||
<div ref="msgs" class="dialog-msgs">
|
||||
<div
|
||||
ref="msgs"
|
||||
class="dialog-msgs"
|
||||
v-longpress="{callback: handleLongpress, delay: 300}">
|
||||
<!--定位提示-->
|
||||
<div v-if="positionShow && positionMsg" class="dialog-position">
|
||||
<div class="position-label" @click="onPositionMark(positionMsg.msg_id)">
|
||||
@ -211,8 +214,6 @@
|
||||
@range="onRange"
|
||||
@visible="onVisible"
|
||||
|
||||
@on-mention="onMention"
|
||||
@on-longpress="onLongpress"
|
||||
@on-view-reply="onViewReply"
|
||||
@on-view-text="onViewText"
|
||||
@on-view-file="onViewFile"
|
||||
@ -653,6 +654,7 @@ import DialogGroupWordChain from "./DialogGroupWordChain";
|
||||
import DialogGroupVote from "./DialogGroupVote";
|
||||
import DialogComplaint from "./DialogComplaint";
|
||||
import touchclick from "../../../directives/touchclick";
|
||||
import longpress from "../../../directives/longpress";
|
||||
import {languageList} from "../../../language";
|
||||
import {isLocalResourcePath} from "../../../components/Replace/utils";
|
||||
import emitter from "../../../store/events";
|
||||
@ -678,7 +680,7 @@ export default {
|
||||
DialogGroupVote,
|
||||
DialogComplaint,
|
||||
},
|
||||
directives: {touchclick},
|
||||
directives: {touchclick, longpress},
|
||||
|
||||
props: {
|
||||
dialogId: {
|
||||
@ -875,6 +877,7 @@ export default {
|
||||
'readLoadNum',
|
||||
'readTimeout',
|
||||
'formOptions',
|
||||
'longpressData',
|
||||
'cacheTranslationLanguage'
|
||||
]),
|
||||
|
||||
@ -3003,6 +3006,92 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
handleLongpress(event) {
|
||||
const {type, data, element} = this.longpressData;
|
||||
this.$store.commit("longpress/clear")
|
||||
//
|
||||
switch (type) {
|
||||
// 长按触发提及
|
||||
case "mention":
|
||||
const user = this.cacheUserBasic.find(({userid}) => userid == data.userid);
|
||||
if (user) {
|
||||
this.$refs.input?.addMention({
|
||||
denotationChar: "@",
|
||||
id: user.userid,
|
||||
value: user.nickname,
|
||||
})
|
||||
}
|
||||
break;
|
||||
|
||||
// 长按触发消息操作
|
||||
case "operateMsg":
|
||||
this.operateVisible = $A.isJson(data) && this.operateItem.id === data.id;
|
||||
this.operateItem = $A.isJson(data) ? data : {};
|
||||
this.operateCopys = []
|
||||
if (event.target.nodeName === 'IMG') {
|
||||
if (this.$Electron) {
|
||||
this.operateCopys.push({
|
||||
type: 'image',
|
||||
icon: '',
|
||||
label: '复制图片',
|
||||
value: $A.thumbRestore(event.target.currentSrc),
|
||||
})
|
||||
}
|
||||
if (data.type !== 'file' && !isLocalResourcePath(event.target.currentSrc)) {
|
||||
this.operateCopys.push({
|
||||
type: 'imagedown',
|
||||
icon: '',
|
||||
label: '下载图片',
|
||||
value: $A.thumbRestore(event.target.currentSrc),
|
||||
})
|
||||
}
|
||||
} else if (event.target.nodeName === 'A') {
|
||||
if (event.target.classList.contains("mention") && event.target.classList.contains("file")) {
|
||||
this.findOperateFile(this.operateItem.id, event.target.href)
|
||||
}
|
||||
this.operateCopys.push({
|
||||
type: 'link',
|
||||
icon: '',
|
||||
label: '复制链接',
|
||||
value: event.target.href,
|
||||
})
|
||||
}
|
||||
this.operateCopys.push({
|
||||
type: 'selected',
|
||||
icon: '',
|
||||
label: '复制选择',
|
||||
value: '',
|
||||
visible: false,
|
||||
})
|
||||
if (data.type === 'text') {
|
||||
if (data.msg.text.replace(/<[^>]+>/g,"").length > 0) {
|
||||
this.operateCopys.push({
|
||||
type: 'text',
|
||||
icon: '',
|
||||
label: null,
|
||||
title: this.operateCopys.length > 1 ? '复制文本' : '复制',
|
||||
value: '',
|
||||
})
|
||||
}
|
||||
if (data.msg.type === 'md') {
|
||||
this.operateCopys.push({
|
||||
type: 'md',
|
||||
icon: '',
|
||||
label: '复制原文',
|
||||
value: '',
|
||||
})
|
||||
}
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.operateItem.clientX = event.clientX
|
||||
this.operateItem.clientY = event.clientY
|
||||
this.onSelectionchange()
|
||||
this.onUpdateOperate(element)
|
||||
})
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
onMsgType(type) {
|
||||
switch (type) {
|
||||
case 'project':
|
||||
@ -3027,83 +3116,6 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
onMention(data) {
|
||||
const user = this.cacheUserBasic.find(({userid}) => userid == data.userid);
|
||||
if (user) {
|
||||
this.$refs.input?.addMention({
|
||||
denotationChar: "@",
|
||||
id: user.userid,
|
||||
value: user.nickname,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onLongpress({event, el, msgData}) {
|
||||
this.operateVisible = this.operateItem.id === msgData.id;
|
||||
this.operateItem = $A.isJson(msgData) ? msgData : {};
|
||||
this.operateCopys = []
|
||||
if (event.target.nodeName === 'IMG') {
|
||||
if (this.$Electron) {
|
||||
this.operateCopys.push({
|
||||
type: 'image',
|
||||
icon: '',
|
||||
label: '复制图片',
|
||||
value: $A.thumbRestore(event.target.currentSrc),
|
||||
})
|
||||
}
|
||||
if (msgData.type !== 'file' && !isLocalResourcePath(event.target.currentSrc)) {
|
||||
this.operateCopys.push({
|
||||
type: 'imagedown',
|
||||
icon: '',
|
||||
label: '下载图片',
|
||||
value: $A.thumbRestore(event.target.currentSrc),
|
||||
})
|
||||
}
|
||||
} else if (event.target.nodeName === 'A') {
|
||||
if (event.target.classList.contains("mention") && event.target.classList.contains("file")) {
|
||||
this.findOperateFile(this.operateItem.id, event.target.href)
|
||||
}
|
||||
this.operateCopys.push({
|
||||
type: 'link',
|
||||
icon: '',
|
||||
label: '复制链接',
|
||||
value: event.target.href,
|
||||
})
|
||||
}
|
||||
this.operateCopys.push({
|
||||
type: 'selected',
|
||||
icon: '',
|
||||
label: '复制选择',
|
||||
value: '',
|
||||
visible: false,
|
||||
})
|
||||
if (msgData.type === 'text') {
|
||||
if (msgData.msg.text.replace(/<[^>]+>/g,"").length > 0) {
|
||||
this.operateCopys.push({
|
||||
type: 'text',
|
||||
icon: '',
|
||||
label: null,
|
||||
title: this.operateCopys.length > 1 ? '复制文本' : '复制',
|
||||
value: '',
|
||||
})
|
||||
}
|
||||
if (msgData.msg.type === 'md') {
|
||||
this.operateCopys.push({
|
||||
type: 'md',
|
||||
icon: '',
|
||||
label: '复制原文',
|
||||
value: '',
|
||||
})
|
||||
}
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.operateItem.clientX = event.clientX
|
||||
this.operateItem.clientY = event.clientY
|
||||
this.onSelectionchange()
|
||||
this.onUpdateOperate(el)
|
||||
})
|
||||
},
|
||||
|
||||
onSelectionchange() {
|
||||
if (!this.operateVisible) {
|
||||
return
|
||||
|
||||
9
resources/assets/js/store/mutations.js
vendored
9
resources/assets/js/store/mutations.js
vendored
@ -284,4 +284,13 @@ export default {
|
||||
$A.IDBSave("dialogQuotes", state.dialogQuotes)
|
||||
}
|
||||
},
|
||||
|
||||
// 长按事件
|
||||
'longpress/set': function(state, {type, data, element}) {
|
||||
state.longpressData = {type, data, element}
|
||||
},
|
||||
|
||||
'longpress/clear': function(state) {
|
||||
state.longpressData = {type: '', data: null, element: null}
|
||||
},
|
||||
}
|
||||
|
||||
5
resources/assets/js/store/state.js
vendored
5
resources/assets/js/store/state.js
vendored
@ -261,5 +261,8 @@ export default {
|
||||
cacheTranscriptionLanguage: '',
|
||||
|
||||
// 下拉菜单操作
|
||||
menuOperation: {}
|
||||
menuOperation: {},
|
||||
|
||||
// 长按数据
|
||||
longpressData: {type: '', data: null, element: null},
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user