Day10:Emit Direct Message II(Render 私人讯息到 HTML)

全文同步於个人 Docusaurus Blog

继承前一章的内容,现在需要将 server-side 接收到的讯息,除了转回到 client-side,同时也要做页面 render 的动作。

Page & Style

先将 HTML 和 CSS 进行部分调整,并添加简单样式,方便待会直接套用在动态生成的内容上。

  <body>
    <main class="wrapper">
      // ...
      <section class="chat-box display-none">
        <p class="username-text">
          登入的使用者:<span class="username-label"></span>
        </p>
      </section>
    </main>
  </body>
.username-text {
  position: absolute;
  top: 20px;
  left: 40px;
  font-size: 36px;
}

.message-left {
  display: inline-block;
  background: white;
  border-radius: 8px 8px 8px 0px;
  border: 1px solid #d5deeb;
  color: black;
  margin: 5px;
  padding: 8px;
}

.message-right {
  float: right;
  background: linear-gradient(168.68deg, #0052c9 1.12%, #0a91db 100%);
  border-radius: 8px 8px 0px 8px;
  color: white;
  margin: 5px;
  padding: 8px;
}

Server

当玩家 A 对玩家 B 发送私人讯息时,server-side 先检查接收讯息的一方是否还在聊天页面中,并建立一组 socket 发给中介层。

// server.js
socket.on('direct-message', (data) => {
  const { receiverSocketId } = data;
  const hasConnectPeer = connectPeers.find(
    (peer) => peer.socketId === receiverSocketId
  );

  if (hasConnectPeer) {
    const authorData = {
      ...data,
      isAuthor: true,
    };
    socket.emit('direct-message', authorData);
    io.to(receiverSocketId).emit('direct-message', data);
  }
});

中介层监听收到资料後,转给 ui 的函式 appendDirectChatMessage() 使用。

// handler.js
socket.on('direct-message', (data) => {
  ui.appendDirectChatMessage(data);
});

Client

在 ui.js 使用资料前,仍要先准备好动态 render 的 HTML。除了传入文字讯息内容,同时也检查目前页面 render 的部分,属於讯息发送者还是接收者,再根据状态决定样式。

// element.js
const getDirectChatMessage = (data) => {
  const { textContent, alighRight } = data;
  const messageContent = document.createElement('div');
  const messageClass = alighRight ? 'message-right' : 'message-left';
  messageContent.innerHTML = `
    <p class="${messageClass}">${textContent}
  `;
  return messageContent;
};

ui.js 接收到中介层的资料後进行解构,根据状态决定抓取接收者或是发送者的 ID。

// ui.js
const appendDirectChatMessage = (messageData) => {
  const { authorSocketId, author, messageContent, receiverSocketId, isAuthor } =
    messageData;
  const messageWrapper = isAuthor
    ? document.getElementById(`${receiverSocketId}-message`)
    : document.getElementById(`${authorSocketId}-message`);

  if (messageWrapper) {
    const data = {
      author,
      textContent: messageContent,
      alighRight: isAuthor ? true : false,
    };
    const message = element.getDirectChatMessage(data);
    messageWrapper.appendChild(message);
  }
};

export default {
  // ...
  appendDirectChatMessage,
};

direct message II


<<:  【面试】自我介绍要点

>>:  成为工具人应有的工具包-11 IE PassView

[Day26]Solidity小实作

hi~经过三天有关solidity语法讲解的过程,那今天就来做一个小实作!我们来写一个有关加法与减...

Day06 - 纯 Html 复杂型别 - object + object collection

结合已提到的 object 及 collection 在 Model Binding 的格式说明 很...

C# delegate 委派 实战篇

我最早开始使用委派 是在开发游戏功能的时候 当时有个需求是需要写一个角色升级的功能 (当年是个人吃人...

原来有一天我可以有其他选择---面试TFT暑期实习计画网页组心得

既然学了网页开发,就希望可以贡献所学,累积不一样的经验;於是,我报名了今年Teach For Tai...

第13天 - (配第11天) 修改MySQL资料表内容,配合下拉式选单

今天内容要搭配【第11天的文章】中的【staff_edit.php (里面含有 INPRUT做修改的...