133 lines
4.3 KiB
JavaScript
133 lines
4.3 KiB
JavaScript
(function () {
|
|
const statusEl = document.getElementById('status');
|
|
const topicEl = document.getElementById('topic');
|
|
const messageEl = document.getElementById('message');
|
|
const btnJoin = document.getElementById('btnJoin');
|
|
const btnLeave = document.getElementById('btnLeave');
|
|
const btnSend = document.getElementById('btnSend');
|
|
const peersEl = document.getElementById('peers');
|
|
const publicKeyEl = document.getElementById('publicKey');
|
|
const logEl = document.getElementById('log');
|
|
const session = BridgeSwarmExamples.sessionStore('chat');
|
|
|
|
function log(msg, type) {
|
|
BridgeSwarmExamples.logLine(logEl, msg, type);
|
|
}
|
|
|
|
function setStatus(msg, isError) {
|
|
statusEl.textContent = msg;
|
|
statusEl.className = 'bs-status' + (isError ? ' error' : '');
|
|
}
|
|
|
|
let swarm = null;
|
|
const connections = [];
|
|
|
|
function updatePeers() {
|
|
peersEl.textContent = 'Peers: ' + connections.length;
|
|
}
|
|
|
|
function setJoinedUi(joined) {
|
|
btnJoin.disabled = joined;
|
|
btnLeave.disabled = !joined;
|
|
messageEl.disabled = !joined;
|
|
btnSend.disabled = !joined;
|
|
}
|
|
|
|
async function joinTopic(topic, opts) {
|
|
if (swarm) return;
|
|
opts = opts || {};
|
|
setStatus('Joining topic "' + topic + '"...');
|
|
swarm = new window.BridgeSwarm(session.swarmOptions('bridge-swarm-chat', topic, opts));
|
|
swarm.on('connection', (conn, peerInfo) => {
|
|
connections.push({ conn, peerInfo });
|
|
updatePeers();
|
|
log('Peer connected: ' + (peerInfo.publicKey || '').slice(0, 16) + '…', 'peer');
|
|
conn.on('data', (data) => {
|
|
const text = new TextDecoder().decode(data);
|
|
log('Received: ' + text, 'msg');
|
|
});
|
|
conn.on('end', () => {
|
|
const i = connections.findIndex(c => c.conn === conn);
|
|
if (i !== -1) connections.splice(i, 1);
|
|
updatePeers();
|
|
log('Peer left', 'sys');
|
|
});
|
|
conn.on('error', (err) => log('Peer error: ' + err.message, 'err'));
|
|
});
|
|
await swarm.join(topic);
|
|
await session.resumeConnections(swarm);
|
|
session.markJoined(swarm, topic);
|
|
const pubKey = await swarm.getPublicKey();
|
|
publicKeyEl.textContent = 'Your public key: ' + pubKey;
|
|
setStatus('Joined "' + topic + '". Send a message or open this page in another tab.');
|
|
setJoinedUi(true);
|
|
log('Joined topic: ' + topic, 'sys');
|
|
}
|
|
|
|
BridgeSwarmExamples.waitForBridgeSwarm().then(async function () {
|
|
var sess = session.load();
|
|
if (sess && sess.active && sess.topic) {
|
|
topicEl.value = sess.topic;
|
|
setStatus('Restoring session…');
|
|
try {
|
|
await joinTopic(sess.topic, { swarmId: sess.swarmId });
|
|
} catch (err) {
|
|
session.clear();
|
|
setStatus(err.message || 'Could not restore session', true);
|
|
log('Error: ' + (err.message || err), 'err');
|
|
}
|
|
return;
|
|
}
|
|
setStatus('Join a topic, then open this page in another tab to chat.');
|
|
}).catch(function (err) {
|
|
setStatus(err.message, true);
|
|
});
|
|
|
|
btnJoin.addEventListener('click', async () => {
|
|
if (typeof window.BridgeSwarm === 'undefined') {
|
|
setStatus('Extension not ready yet. Wait a moment and try again.', true);
|
|
return;
|
|
}
|
|
const topic = topicEl.value.trim() || 'default-topic';
|
|
if (swarm) return;
|
|
try {
|
|
await joinTopic(topic);
|
|
} catch (err) {
|
|
setStatus('Error: ' + err.message, true);
|
|
log('Error: ' + err.message, 'err');
|
|
}
|
|
});
|
|
|
|
btnLeave.addEventListener('click', async () => {
|
|
if (!swarm) return;
|
|
try {
|
|
const topic = topicEl.value.trim() || 'default-topic';
|
|
await swarm.leave(topic);
|
|
await swarm.destroy();
|
|
connections.length = 0;
|
|
updatePeers();
|
|
swarm = null;
|
|
session.clear();
|
|
setStatus('Left topic. You can join again.');
|
|
setJoinedUi(false);
|
|
log('Left topic', 'sys');
|
|
} catch (err) {
|
|
log('Error: ' + err.message, 'err');
|
|
}
|
|
});
|
|
|
|
function sendMessage() {
|
|
const text = messageEl.value.trim();
|
|
if (!text || !swarm || connections.length === 0) return;
|
|
const data = new TextEncoder().encode(text);
|
|
connections.forEach(({ conn }) => {
|
|
try { conn.write(data); } catch (e) {}
|
|
});
|
|
log('Sent: ' + text, 'msg');
|
|
messageEl.value = '';
|
|
}
|
|
|
|
btnSend.addEventListener('click', sendMessage);
|
|
messageEl.addEventListener('keydown', (e) => { if (e.key === 'Enter') sendMessage(); });
|
|
})();
|