mirror of
https://github.com/jackyzha0/quartz.git
synced 2026-03-21 21:45:42 -05:00
3.2 KiB
3.2 KiB
| tags | session | duration | status | |||||
|---|---|---|---|---|---|---|---|---|
|
7 | 2 hours | ready |
Session 7 — Connecting the UI to the WebSocket
🎯 Objectives
- Connect the Renderer UI to the WebSocket via IPC
- Display incoming messages dynamically in the DOM
- Send messages from the input field
- Handle connection states and polish the UX
🧠 Architecture Recap
[Renderer UI]
↕ ipcRenderer (via preload.js)
[Main Process]
↕ WebSocket
[Other Clients]
The Renderer doesn't touch WebSocket directly — it talks to Main via IPC, and Main relays to/from the WebSocket server.
🧠 Concepts Covered
Forwarding WebSocket Messages via IPC
// main.js — when a WS message arrives, forward to renderer
wss.on('connection', (socket) => {
socket.on('message', (data) => {
// Broadcast to all WS clients
wss.clients.forEach(client => {
if (client.readyState === 1) client.send(data.toString())
})
// Also send to our own renderer window
mainWindow.webContents.send('new-message', JSON.parse(data.toString()))
})
})
Exposing the API via preload.js
// preload.js
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('chatAPI', {
sendMessage: (message) => ipcRenderer.send('send-message', message),
onMessage: (callback) => ipcRenderer.on('new-message', (_, msg) => callback(msg))
})
Renderer: Sending & Displaying Messages
// renderer/app.js
const form = document.getElementById('message-form')
const input = document.getElementById('message-input')
const chatBox = document.getElementById('chat-box')
// Send a message
form.addEventListener('submit', (e) => {
e.preventDefault()
const text = input.value.trim()
if (!text) return
window.chatAPI.sendMessage({
username: localStorage.getItem('username') || 'Anonymous',
text,
timestamp: new Date().toLocaleTimeString()
})
input.value = ''
})
// Receive messages
window.chatAPI.onMessage((msg) => {
const div = document.createElement('div')
div.className = 'message'
div.innerHTML = `
<span class="username">${msg.username}</span>
<span class="text">${msg.text}</span>
<span class="time">${msg.timestamp}</span>
`
chatBox.appendChild(div)
chatBox.scrollTop = chatBox.scrollHeight
})
Connection State UI
// Show "connecting..." / "connected" / "disconnected" states
ipcRenderer.on('ws-status', (_, status) => {
document.getElementById('status').textContent = status
document.getElementById('status').className = status
})
🛠 Hands-on Exercise — Complete the App (80 min)
- Wire up
preload.jswithchatAPI - Implement the message send handler
- Implement the message receive + DOM append
- Style the chat bubbles in
style.css - Add username prompt on app start (
prompt()or a simple input screen) - Test across 3+ laptops on the same network
Bonus challenges:
- Show "User X joined" when someone connects
- Different color bubbles for your messages vs others
- Sound notification on new message
- Timestamp on each message
📦 Resources
- Session 6 - WebSocket Server ← previous
- Session 8 - Packaging & Distribution ← next