补上好友申请前后关系状态聊天页的入口,并把验证留言渲染成真实消息气泡
第3章要求pending_inbound/pending_outbound/none/blocked几种关系状态都能在真实聊天 窗口里看到(参考图 个人对话框(对方的状态)/(我的状态).png、开启沟通页面.png)。 messages-view.jsx里对应的横幅逻辑("以上是打招呼的消息"/"好友申请正在等待处理"等) 本身早就是对的,但排查发现两个问题: 1. 全项目没有任何入口能导航进这个视图——"新朋友"列表(FriendRequests)每一行没有 onClick;好友个人主页(Profile)非好友分支只显示一段cannotAddReason纯文字,没有 任何可点击进聊天的按钮。发起方和接收方在成为好友之前都完全看不到这个视图。 2. 验证留言原文(发好友申请时填的那段话,存在im_friend_requests表的message字段, 不是真实Tinode消息,没有走topic.publish())没有被当作消息渲染出来,参考图里 明确是作为聊天页第一条消息气泡展示的。 修复: - contact-management-view.jsx: FriendRequests每一行加onClick,用(onCreateTopic|| onTopicSelected)跳进对应聊天(同一套Profile.openChat已经验证过的冷启动安全写法, 接受/拒绝按钮补stopPropagation不受影响);Profile非好友分支(blocked_by_peer/ blocked_by_me/pending_inbound/pending_outbound)补一个"查看聊天"按钮,跟 cannotAddReason文字并排展示(不复用people-profile-actions的两列grid,那是给 发消息+音视频通话两个平级按钮设计的)。ContactManagementView/sidepanel-view.jsx 早前就已经把onCreateTopic透传到位,这次只是多接一层。 - messages-view.jsx: loadRelationshipContext新增loadPendingRequestMessage, relationship是pending_inbound/pending_outbound时,用relationshipContext自带的 request_id去GET /friend-requests换真实留言文本(没有留言用参考图默认文案"请求 添加你为好友"兜底),渲染成一条合成的消息气泡插在消息列表最前面(不进 messageNodes、不调用发消息接口)——pending_inbound左对齐、pending_outbound右 对齐,气泡样式直接复用chat-message.jsx真实消息已经在用的.bubble/.left/.right 这套CSS(app里"发出的"气泡实际是这套已实现的浅色而非参考图的蓝色,保持跟同一 会话里其它真实消息一致,不単独改这一条的颜色去凑旧版参考图)。 验证:真实两个新账号(vcm909641发起→hankqa14b接收)走了一遍完整流程—— 从"新朋友"列表点击行正确进入聊天页,留言气泡+"以上是打招呼的消息"横幅正确显示; 从Profile页"查看聊天"进入,留言气泡右对齐+"好友申请正在等待处理"横幅正确显示; 点"通过验证"接受申请后正确留在列表页不误触发导航;接受后重新打开同一会话, 合成气泡正确消失,被真实的"你们已成为好友,现在可以开始聊天了。"系统消息取代, 无残留/无重复。
This commit is contained in:
@@ -47,7 +47,7 @@ import { CALL_STATE_OUTGOING_INITATED, CALL_STATE_IN_PROGRESS } from '../constan
|
||||
import { blobToBase64, fileToBase64, imageScaled, importVCard, makeImageUrl } from '../lib/blob-helpers.js';
|
||||
import { topicDisplayName } from '../lib/utils.js';
|
||||
import { acceptGroupInvitation, checkURL, confirmRiskChallenge, createChatUploader, favoriteMessages, getBootstrap,
|
||||
getConversationContext, getFavorites, getGroupJoinRequests, getGroupMembers, getLatestGroupAnnouncement,
|
||||
getConversationContext, getFavorites, getFriendRequests, getGroupJoinRequests, getGroupMembers, getLatestGroupAnnouncement,
|
||||
getTopicDraft, recallMessage, updateTopicDraft } from '../lib/im-api.js';
|
||||
import HashNavigation from '../lib/navigation.js';
|
||||
import { bytesToHumanSize, relativeDateFormat, shortDateFormat } from '../lib/strformat.js';
|
||||
@@ -495,6 +495,7 @@ class MessagesView extends React.Component {
|
||||
selectedPin: 0,
|
||||
subsVersion: 0,
|
||||
relationshipContext: null,
|
||||
pendingRequestMessage: null,
|
||||
groupRoles: null,
|
||||
myGroupRole: null,
|
||||
groupAnnouncement: null,
|
||||
@@ -523,6 +524,7 @@ class MessagesView extends React.Component {
|
||||
dragging: false,
|
||||
selectedPin: 0,
|
||||
relationshipContext: null,
|
||||
pendingRequestMessage: null,
|
||||
groupRoles: null,
|
||||
myGroupRole: null,
|
||||
groupAnnouncement: null,
|
||||
@@ -1251,12 +1253,48 @@ class MessagesView extends React.Component {
|
||||
}
|
||||
const topicName = topic.name;
|
||||
getConversationContext(topicName).then(data => {
|
||||
if (this.state.topic == topicName) {
|
||||
this.setState({relationshipContext: data});
|
||||
if (this.state.topic != topicName) {
|
||||
return;
|
||||
}
|
||||
this.setState({relationshipContext: data});
|
||||
this.loadPendingRequestMessage(topicName, data);
|
||||
}).catch(_ => {});
|
||||
}
|
||||
|
||||
// 个人对话框(对方的状态).png / (我的状态).png:pending_inbound/pending_outbound 关系下,聊天
|
||||
// 页顶部第一条应该是发起好友申请时留的验证留言原文,以真实消息气泡的样式渲染(对方发的居左、
|
||||
// 自己发的居右),下面再跟现有的 #relationship-status-note 横幅。这条留言从来不是一条真实的
|
||||
// Tinode 消息(没有走 topic.publish(),只存在 im_friend_requests 表的 message 字段里),所以
|
||||
// 不会自然出现在 messageNodes 里——relationshipContextPayload 已经带了 request_id,用它去
|
||||
// GET /friend-requests 换真实留言文本;找不到(比如留言本身是空的)就回退成参考图里的默认文案。
|
||||
loadPendingRequestMessage(topicName, ctx) {
|
||||
const relationship = ctx && ctx.relationship;
|
||||
if (relationship != 'pending_inbound' && relationship != 'pending_outbound') {
|
||||
this.setState({pendingRequestMessage: null});
|
||||
return;
|
||||
}
|
||||
if (!ctx.request_id) {
|
||||
this.setState({pendingRequestMessage: {text: '请求添加你为好友', response: relationship == 'pending_inbound', ts: null}});
|
||||
return;
|
||||
}
|
||||
const direction = relationship == 'pending_inbound' ? 'inbound' : 'outbound';
|
||||
getFriendRequests(direction, 'all').then(data => {
|
||||
if (this.state.topic != topicName) {
|
||||
return;
|
||||
}
|
||||
const match = (data.items || []).find(item => item.request_id == ctx.request_id);
|
||||
this.setState({pendingRequestMessage: {
|
||||
text: (match && match.message) || '请求添加你为好友',
|
||||
response: relationship == 'pending_inbound',
|
||||
ts: match ? new Date(match.created_at) : null
|
||||
}});
|
||||
}).catch(_ => {
|
||||
if (this.state.topic == topicName) {
|
||||
this.setState({pendingRequestMessage: {text: '请求添加你为好友', response: relationship == 'pending_inbound', ts: null}});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Ch.6: role badges (docs/images/群标识.png) and the announcement/join-request banners at the top of a
|
||||
// group chat (docs/images/群公告状态.png, 新邀请进群申请.png) all need data no P2P topic has -- fetch it
|
||||
// once per group-topic-load, same best-effort pattern as loadRelationshipContext above. Every `topic`
|
||||
@@ -2586,6 +2624,22 @@ class MessagesView extends React.Component {
|
||||
</button>
|
||||
<div id="messages-panel" ref={this.handleScrollReference}>
|
||||
<ul id="scroller" className={chatBoxClass}>
|
||||
{this.state.pendingRequestMessage ?
|
||||
<>
|
||||
{this.state.pendingRequestMessage.ts ?
|
||||
<MetaMessage date={relativeDateFormat(this.state.pendingRequestMessage.ts)}
|
||||
locale={this.props.intl.locale} key="pending-request-date" /> : null}
|
||||
<li className={'single ' + (this.state.pendingRequestMessage.response ? 'left' : 'right')}
|
||||
key="pending-request-message">
|
||||
<div>
|
||||
<div className="bubble tip">
|
||||
<div className="content-meta">
|
||||
<div className="message-content">{this.state.pendingRequestMessage.text}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</> : null}
|
||||
{messageNodes}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user