整理右键、长按

This commit is contained in:
kuaifan 2022-06-03 09:36:14 +08:00
parent e15f7f6377
commit a2dcd69efd
6 changed files with 100 additions and 72 deletions

View File

@ -156,8 +156,8 @@
<i class="taskfont">&#xe6f3;</i>
<div class="menu-title">{{$L('文件')}}</div>
</li>
<li class="menu-project">
<ul ref="projectWrapper" :class="listClassName" @scroll="operateVisible = false">
<li ref="menuProject" class="menu-project">
<ul :class="listClassName" @scroll="operateVisible = false">
<li
v-for="(item, key) in projectLists"
:ref="`project_${item.id}`"
@ -192,6 +192,7 @@
<div class="operate-position" :style="operateStyles">
<Dropdown
trigger="custom"
:placement="$isDesktop ? 'bottom' : 'top'"
:visible="operateVisible"
@on-clickoutside="operateVisible = false"
transfer>
@ -1008,7 +1009,7 @@ export default {
this.operateItem = $A.isJson(projectItem) ? projectItem : {};
this.$nextTick(() => {
const projectRect = el.getBoundingClientRect();
const wrapRect = this.$refs.projectWrapper.getBoundingClientRect();
const wrapRect = this.$refs.menuProject.getBoundingClientRect();
this.operateStyles = {
left: `${event.clientX - wrapRect.left}px`,
top: `${projectRect.top}px`,
@ -1027,7 +1028,7 @@ export default {
}).then(({data}) => {
this.$store.dispatch("saveProject", data);
this.$nextTick(() => {
const active = this.$refs.projectWrapper.querySelector(".active")
const active = this.$refs.menuProject.querySelector(".active")
if (active) {
$A.scrollToView(active, {
behavior: 'instant',

View File

@ -7,7 +7,10 @@
<div class="dialog-head">
<!--详情-->
<div class="dialog-content" :class="contentClass">
<div
class="dialog-content"
:class="contentClass"
v-longpress="handleLongpress">
<!--文本-->
<div v-if="msgData.type === 'text'" class="content-text no-dark-content">
<pre @click="viewText" v-html="textMsg(msgData.msg.text)"></pre>
@ -60,17 +63,6 @@
<!--未知-->
<div v-else class="content-unknown">{{$L("未知的消息类型")}}</div>
</div>
<!--菜单-->
<div v-if="showMenu" class="dialog-menu">
<div class="menu-icon">
<Icon v-if="msgData.userid == userId" @click="withdraw" type="md-undo" :title="$L('撤回')"/>
<template v-if="msgData.type === 'file'">
<Icon @click="viewFile" type="md-eye" :title="$L('查看')"/>
<Icon @click="downFile" type="md-arrow-round-down" :title="$L('下载')"/>
</template>
</div>
</div>
</div>
<!--时间/阅读-->
@ -117,10 +109,12 @@
import WCircle from "../../../components/WCircle";
import {mapState} from "vuex";
import {Store} from "le5le-store";
import longpress from "../../../directives/longpress";
export default {
name: "DialogView",
components: {WCircle},
directives: {longpress},
props: {
msgData: {
type: Object,
@ -167,10 +161,6 @@ export default {
return this.allList.filter(({read_at}) => !read_at)
},
showMenu() {
return this.msgData.userid == this.userId || this.msgData.type === 'file'
},
contentClass() {
const {type, msg} = this.msgData;
const classArray = [];
@ -203,6 +193,14 @@ export default {
},
methods: {
handleLongpress(event, el) {
this.$emit("on-longpress", {
event,
el,
msgData: this.msgData
})
},
msgRead() {
if (this.msgData._r === true) {
return;

View File

@ -94,7 +94,12 @@
<div class="dialog-avatar">
<UserAvatar :userid="item.userid" :tooltipDisabled="item.userid == userId" :size="30"/>
</div>
<DialogView :msg-data="item" :dialog-type="dialogData.type" :hide-percentage="isMyDialog"/>
<DialogView
:ref="`msg_${item.id}`"
:msg-data="item"
:dialog-type="dialogData.type"
:hide-percentage="isMyDialog"
@on-longpress="onLongpress"/>
</DynamicScrollerItem>
</template>
</DynamicScroller>
@ -125,6 +130,25 @@
<div v-if="dialogDrag" class="drag-over" @click="dialogDrag=false">
<div class="drag-text">{{$L('拖动到这里发送')}}</div>
</div>
<div class="operate-position" :style="operateStyles">
<Dropdown
trigger="custom"
:placement="$isDesktop ? 'bottom' : 'top'"
:visible="operateVisible"
@on-clickoutside="operateVisible = false"
@on-click="onOperate"
transfer>
<div :style="{userSelect:operateVisible ? 'none' : 'auto', height: operateStyles.height}"></div>
<DropdownMenu slot="list">
<DropdownItem name="forward">{{ $L('转发') }}</DropdownItem>
<DropdownItem v-if="operateItem.userid == userId" name="withdraw">{{ $L('撤回') }}</DropdownItem>
<template v-if="operateItem.type === 'file'">
<DropdownItem name="view" divided>{{ $L('查看文件') }}</DropdownItem>
<DropdownItem name="down">{{ $L('下载文件') }}</DropdownItem>
</template>
</DropdownMenu>
</Dropdown>
</div>
<!--拖动发送提示-->
<Modal
@ -232,6 +256,10 @@ export default {
groupInfoShow: false,
wrapperStyle: {},
operateStyles: {},
operateVisible: false,
operateItem: {},
}
},
@ -704,6 +732,7 @@ export default {
},
onScroll() {
this.operateVisible = false;
this.__onScroll && clearTimeout(this.__onScroll);
this.__onScroll = setTimeout(_ => {
const {scrollE} = this.scrollInfo();
@ -722,6 +751,41 @@ export default {
}
},
onLongpress({event, el, msgData}) {
this.operateVisible = false;
this.operateItem = $A.isJson(msgData) ? msgData : {};
this.$nextTick(() => {
const projectRect = el.getBoundingClientRect();
const wrapRect = this.$el.getBoundingClientRect();
this.operateStyles = {
left: `${event.clientX - wrapRect.left}px`,
top: `${projectRect.top}px`,
height: projectRect.height + 'px',
}
this.operateVisible = true;
})
},
onOperate(name) {
switch (name) {
case "forward":
// todo
break;
case "withdraw":
this.$refs[`msg_${this.operateItem.id}`].withdraw()
break;
case "view":
this.$refs[`msg_${this.operateItem.id}`].viewFile()
break;
case "down":
this.$refs[`msg_${this.operateItem.id}`].downFile()
break;
}
},
backListener(e) {
e.preventDefault()
},

View File

@ -11,7 +11,7 @@
</Input>
</div>
</div>
<ul ref="projectWrapper" @scroll="operateVisible = false">
<ul @scroll="operateVisible = false">
<template v-if="projectLists.length === 0">
<li v-if="projectKeyLoading > 0" class="loading"><Loading/></li>
<li v-else class="nothing">
@ -55,7 +55,7 @@
<div class="operate-position" :style="operateStyles">
<Dropdown
trigger="custom"
placement="top"
:placement="$isDesktop ? 'bottom' : 'top'"
:visible="operateVisible"
@on-clickoutside="operateVisible = false"
transfer>
@ -181,7 +181,7 @@ export default {
this.operateItem = $A.isJson(projectItem) ? projectItem : {};
this.$nextTick(() => {
const projectRect = el.getBoundingClientRect();
const wrapRect = this.$refs.projectWrapper.getBoundingClientRect();
const wrapRect = this.$el.getBoundingClientRect();
this.operateStyles = {
left: `${event.clientX - wrapRect.left}px`,
top: `${projectRect.top}px`,

View File

@ -32,7 +32,6 @@
static>
<ul
v-if="tabActive==='dialog'"
ref="dialogWrapper"
class="dialog">
<li v-if="dialogList.length === 0" class="nothing">
{{$L(dialogKey ? `没有任何与"${dialogKey}"相关的会话` : `没有任何会话`)}}
@ -103,10 +102,10 @@
<div class="operate-position" :style="operateStyles">
<Dropdown
trigger="custom"
:transfer="true"
:placement="$isDesktop ? 'bottom' : 'top'"
:visible="operateVisible"
@on-clickoutside="operateVisible = false">
@on-clickoutside="operateVisible = false"
transfer>
<div :style="{userSelect:operateVisible ? 'none' : 'auto', height: operateStyles.height}"></div>
<DropdownMenu slot="list">
<DropdownItem @click.native="handleTopClick">
@ -551,7 +550,7 @@ export default {
this.operateItem = $A.isJson(dialogItem) ? dialogItem : {};
this.$nextTick(() => {
const dialogRect = el.getBoundingClientRect();
const wrapRect = this.$refs.dialogWrapper.getBoundingClientRect();
const wrapRect = this.$refs.list.$el.getBoundingClientRect();
this.operateStyles = {
left: `${event.clientX - wrapRect.left}px`,
top: `${dialogRect.top}px`,

View File

@ -219,14 +219,6 @@
max-width: 70%;
}
&:hover {
.dialog-head {
.dialog-menu {
opacity: 1;
}
}
}
.dialog-username {
max-width: 100%;
height: 22px;
@ -557,37 +549,6 @@
text-decoration: underline;
}
}
.dialog-menu {
opacity: 0;
margin-left: 6px;
transition: all 0.3s;
.menu-icon {
display: flex;
align-items: center;
border-radius: 4px;
border: 1px solid #ddd;
background-color: #ffffff;
> i {
flex: 1;
display: inline-block;
padding: 4px 6px;
color: #999;
font-size: 13px;
cursor: pointer;
& + i {
border-left: 1px solid #ddd;
}
&:hover {
color: #777;
}
}
}
}
}
.dialog-foot {
@ -768,11 +729,6 @@
}
}
}
.dialog-menu {
margin-left: 0;
margin-right: 6px;
}
}
.dialog-foot {
@ -873,6 +829,16 @@
color: $primary-text-color;
}
}
.operate-position {
position: absolute;
top: 0;
right: 0;
width: 1px;
opacity: 0;
visibility: hidden;
pointer-events: none;
}
}
.dialog-wrapper-read-poptip {