修复长按消息气泡弹出自定义菜单时,浏览器/系统原生右键菜单跟着一起弹出的问题

chat-message.jsx 新增 suppressNativeContextMenu,在气泡上监听 contextmenu 事件并 preventDefault,
避免长按(或桌面端右键/触屏模拟长按)触发的原生上下文菜单和应用自己的长按菜单重叠显示。
css/base.css 给 .bubble 补了 -webkit-touch-callout:none,同时覆盖 iOS Safari 那条独立于
contextmenu 事件之外的长按呼出菜单(复制/查询/分享...),不影响 user-select,桌面端正常的
点击拖拽选字复制不受影响。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-09-07 19:50:06 +08:00
co-authored by Claude Sonnet 5
parent 4ce666042e
commit 48baeceaa8
5 changed files with 23 additions and 3 deletions
+11 -1
View File
@@ -65,6 +65,7 @@ class BaseChatMessage extends React.PureComponent {
this.handleTouchStart = this.handleTouchStart.bind(this);
this.handleTouchMove = this.handleTouchMove.bind(this);
this.handleTouchEnd = this.handleTouchEnd.bind(this);
this.suppressNativeContextMenu = this.suppressNativeContextMenu.bind(this);
this.handleCancelUpload = this.handleCancelUpload.bind(this);
this.handleDraftyClick = this.handleDraftyClick.bind(this);
this.handleVoicePlayed = this.handleVoicePlayed.bind(this);
@@ -208,6 +209,14 @@ class BaseChatMessage extends React.PureComponent {
this.longPressOrigin = null;
}
// The press-and-hold gesture above is our own timer-based approximation of "long press" -- it
// doesn't stop the browser's own native context menu (right-click on desktop, or the OS-level
// long-press menu some browsers still fire as a real `contextmenu` event even for a touch/mouse
// hold). Left alone, both menus show up stacked on top of each other.
suppressNativeContextMenu(e) {
e.preventDefault();
}
componentWillUnmount() {
this.cancelLongPress();
}
@@ -472,7 +481,8 @@ class BaseChatMessage extends React.PureComponent {
<i className="material-icons red message-fail-icon">error</i> : null}
<div>
<div className={bubbleClass}
onTouchStart={this.handleTouchStart} onTouchMove={this.handleTouchMove} onTouchEnd={this.handleTouchEnd}>
onTouchStart={this.handleTouchStart} onTouchMove={this.handleTouchMove} onTouchEnd={this.handleTouchEnd}
onContextMenu={this.suppressNativeContextMenu}>
{showVoiceUnreadDot ? <i className="voice-unread-dot" /> : null}
<div className="content-meta">
<div className={textSizeClass}>