diff --git a/resources/assets/js/pages/manage/components/DialogWrapper.vue b/resources/assets/js/pages/manage/components/DialogWrapper.vue
index 76a4a58cf..b4a30cd33 100644
--- a/resources/assets/js/pages/manage/components/DialogWrapper.vue
+++ b/resources/assets/js/pages/manage/components/DialogWrapper.vue
@@ -328,9 +328,13 @@
{{ $L('翻译') }}
-
+
- {{ $L(item.label) }}
+ {{ $L(item.label || item.title) }}
@@ -650,6 +654,7 @@ import {languageList} from "../../../language";
import {isLocalResourcePath} from "../../../components/Replace/utils";
import emitter from "../../../store/events";
import Forwarder from "./Forwarder/index.vue";
+import {throttle} from "lodash";
export default {
name: "DialogWrapper",
@@ -823,9 +828,11 @@ export default {
mounted() {
emitter.on('websocketMsg', this.onWebsocketMsg);
emitter.on('dialogMsgChange', this.onMsgChange);
+ this.windowTouch && document.addEventListener('selectionchange', this.onSelectionchange);
},
beforeDestroy() {
+ this.windowTouch && document.removeEventListener('selectionchange', this.onSelectionchange);
emitter.off('dialogMsgChange', this.onMsgChange);
emitter.off('websocketMsg', this.onWebsocketMsg);
this.generateUnreadData(this.dialogId)
@@ -2884,9 +2891,10 @@ export default {
}
},
- onScroll(event) {
- if (this.operatePreventScroll === 0) {
- this.operateVisible = false;
+ onScroll({target}) {
+ this.onThrottleScroll(target)
+ if (this.operateVisible) {
+ this.onUpdateOperate(target.querySelector(`[data-id="${this.operateItem.id}"]`)?.querySelector(".dialog-head"))
}
//
const {offset, tail} = this.scrollInfo();
@@ -2897,7 +2905,7 @@ export default {
this.scrollToBottomRefresh && this.onReGetMsg()
}
//
- this.scrollAction = event.target.scrollTop;
+ this.scrollAction = target.scrollTop;
this.scrollDirection = this.scrollTmp <= this.scrollAction ? 'down' : 'up';
setTimeout(_ => this.scrollTmp = this.scrollAction, 0);
//
@@ -2905,6 +2913,12 @@ export default {
setTimeout(_=> this.scrollIng--, 100);
},
+ onThrottleScroll: throttle(function (target) {
+ if (this.operatePreventScroll === 0 && this.operateVisible) {
+ this.operateVisible = !!this.getSelectedTextInElement(target)
+ }
+ }, 100),
+
onRange(range) {
if (this.preventRangeLoad > 0) {
return
@@ -2999,13 +3013,23 @@ export default {
this.operateVisible = this.operateItem.id === msgData.id;
this.operateItem = $A.isJson(msgData) ? msgData : {};
this.operateCopys = []
- if (event.target.nodeName === 'IMG' && this.$Electron) {
- this.operateCopys.push({
- type: 'image',
- icon: '',
- label: '复制图片',
- value: $A.thumbRestore(event.target.currentSrc),
- })
+ if (event.target.nodeName === 'IMG') {
+ if (this.$Electron) {
+ this.operateCopys.push({
+ type: 'image',
+ icon: '',
+ label: '复制图片',
+ value: $A.thumbRestore(event.target.currentSrc),
+ })
+ }
+ if (!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)
@@ -3017,33 +3041,20 @@ export default {
value: event.target.href,
})
}
+ this.operateCopys.push({
+ type: 'selected',
+ icon: '',
+ label: '复制选择',
+ value: '',
+ visible: false,
+ })
if (msgData.type === 'text') {
- if (event.target.nodeName === 'IMG' && !isLocalResourcePath(event.target.currentSrc)) {
- this.operateCopys.push({
- type: 'imagedown',
- icon: '',
- label: '下载图片',
- value: $A.thumbRestore(event.target.currentSrc),
- })
- }
- const selectText = this.getSelectedTextInElement(el)
- if (selectText.length > 0) {
- this.operateCopys.push({
- type: 'selected',
- icon: '',
- label: '复制选择',
- value: selectText,
- })
- }
if (msgData.msg.text.replace(/<[^>]+>/g,"").length > 0) {
- let label = this.operateCopys.length > 0 ? '复制文本' : '复制'
- if (selectText.length > 0) {
- label = '复制全部'
- }
this.operateCopys.push({
type: 'text',
icon: '',
- label,
+ label: null,
+ title: this.operateCopys.length > 1 ? '复制文本' : '复制',
value: '',
})
}
@@ -3057,34 +3068,64 @@ export default {
}
}
this.$nextTick(() => {
- const rect = el.getBoundingClientRect();
- const scrollerRect = this.$refs.scroller.$el.getBoundingClientRect();
- let top = rect.top + this.windowScrollY,
- height = rect.height;
- if (rect.top < scrollerRect.top) {
- top = scrollerRect.top
- height -= scrollerRect.top - rect.top
- }
- if (rect.bottom > scrollerRect.bottom) {
- height -= rect.bottom - scrollerRect.bottom
- }
- const left = this.windowWidth < 500 ? (this.windowWidth / 2) : event.clientX
- this.operateStyles = {
- left: `${left}px`,
- top: `${top}px`,
- height: `${height}px`,
- }
- this.operateClient = {x: left, y: event.clientY};
- if (this.operateVisible) {
- try {
- this.$refs.operate.$refs.drop.popper.update()
- } catch (e) {}
- } else {
- this.operateVisible = true;
- }
+ this.operateItem.clientX = event.clientX
+ this.operateItem.clientY = event.clientY
+ this.onSelectionchange()
+ this.onUpdateOperate(el)
})
},
+ onSelectionchange() {
+ if (!this.operateVisible) {
+ return
+ }
+ const selectedItem = this.operateCopys.find(({type}) => type === 'selected')
+ if (!selectedItem) {
+ return;
+ }
+ const selectText = this.getSelectedTextInElement(this.$refs.scroller.$el.querySelector(`[data-id="${this.operateItem.id}"]`))
+ selectedItem.value = selectText
+ selectedItem.visible = selectText.length > 0
+ //
+ const textItem = this.operateCopys.find(({type}) => type === 'text');
+ if (!textItem) {
+ return;
+ }
+ textItem.label = selectText.length > 0 ? '复制全部' : null
+ },
+
+ onUpdateOperate(el) {
+ if (!el) {
+ return
+ }
+ //
+ const rect = el.getBoundingClientRect();
+ const scrollerRect = this.$refs.scroller.$el.getBoundingClientRect();
+ let top = rect.top + this.windowScrollY,
+ height = rect.height;
+ if (rect.top < scrollerRect.top) {
+ top = scrollerRect.top
+ height -= scrollerRect.top - rect.top
+ }
+ if (rect.bottom > scrollerRect.bottom) {
+ height -= rect.bottom - scrollerRect.bottom
+ }
+ const left = this.windowWidth < 500 ? (this.windowWidth / 2) : this.operateItem.clientX
+ this.operateStyles = {
+ left: `${left}px`,
+ top: `${top}px`,
+ height: `${height}px`,
+ }
+ this.operateClient = {x: left, y: this.operateItem.clientY};
+ if (this.operateVisible) {
+ try {
+ this.$refs.operate.$refs.drop.popper.update()
+ } catch (e) {}
+ } else {
+ this.operateVisible = true;
+ }
+ },
+
onOperate(action, value = null) {
this.operateVisible = false;
this.$nextTick(_ => {
@@ -3487,9 +3528,9 @@ export default {
break;
case 'text':
- const copyEl = $A(this.$refs.scroller.$el).find(`[data-id="${this.operateItem.id}"]`).find('.dialog-content')
- if (copyEl.length > 0) {
- let copyText = copyEl[0].innerText;
+ const copyEl = this.$refs.scroller.$el.querySelector(`[data-id="${this.operateItem.id}"]`)?.querySelector(".dialog-content")
+ if (copyEl) {
+ let copyText = copyEl.innerText;
if ($A.getObject(this.operateItem.msg, 'type') !== 'md') {
copyText = copyText.replace(/\n\n/g, "\n").replace(/(^\s*)|(\s*$)/g, "")
}
@@ -4170,17 +4211,14 @@ export default {
},
getSelectedTextInElement(element) {
- let selectedText = "";
- if (window.getSelection) {
- let selection = window.getSelection();
- if (selection.rangeCount > 0) {
- const range = selection.getRangeAt(0);
- if (element.contains(range.commonAncestorContainer)) {
- selectedText = range.toString();
- }
+ const selection = document.getSelection();
+ if (selection.rangeCount > 0) {
+ const range = selection.getRangeAt(0);
+ if (element.contains(range.commonAncestorContainer)) {
+ return range.toString();
}
}
- return selectedText;
+ return "";
},
onViewAvatar(e) {