Skip to content

Instantly share code, notes, and snippets.

@legodude17
Last active February 17, 2017 19:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save legodude17/889e86bbdbcc122aae689dfdcb3149ec to your computer and use it in GitHub Desktop.
Save legodude17/889e86bbdbcc122aae689dfdcb3149ec to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Peer Chat</title>
<style media="screen">
body {
width: 100%;
height: 100%;
}
html {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="room">
<input type="text" name="roomId" id="roomId" placeholder="Room Id" /><button id="join">Join</button>
-- OR --
<button id="create">Create a new room</button>
</div>
<div id="info" style="display:none;">
<input type="text" name="username" id="name" placeholder="Your name" value="Anonymous"/><button id="go">Go</button>
</div>
<div id="loading" style="display:none;">
Loading room...
</div>
<div id="main" style="display:none;">
<ul id="messages">
</ul>
<input type="text" name="messsage" id="messsage" placeholder="Type you message here..." /><button id="send">Send</button>
<span id="id"></span>
</div>
<div>
<ul id="log">
</ul>
</div>
<script src="https://legodude17.github.io/host/peerjs.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
function log(type, text) {
views.log.appendChild(document.createElement('li')).innerHTML = `<strong>${type}</strong>: ${text}`;
}
try {
var views = {
$defaults: [
'roomId',
'room',
'join',
'create',
'info',
'name',
'go',
'loading',
'main',
'messages',
'message',
'send',
'id',
'log'
]
};
var id = (Math.random() * Date.now()) + "";
var state = {
roomId: null,
name: null,
id,
peer: null,
created: false,
room: {
memebers: {},
isOwner: false,
messages: []
}
};
if ((roomId = location.search.match(/[?&]id=([0-9\.]+)/))) {
views.roomId.value = roomId[1];
views.roomId.disabled = true;
}
var message = {
join() {
return {
type: 'join'
}
},
ack(members) {
return {
type: 'acknowledge',
members
}
},
message(text) {
return {
type: 'message',
text
}
}
};
function room() {
function handleRoomClick(e) {
if (e.target === views.join) {
state.roomId = views.roomId.value;
} else {
state.roomId = id;
state.created = true;
}
views.join.removeEventListener('click', handleRoomClick);
views.create.removeEventListener('click', handleRoomClick);
views.room.style.display = 'none';
log('debug', `Id is ${state.roomId}, and you ${state.created ? 'created' : 'did not create'} this room`);
info();
}
views.join.addEventListener('click', handleRoomClick);
views.create.addEventListener('click', handleRoomClick);
log('debug', 'room() adding event listeners');
}
function info() {
views.info.style.display = 'block';
views.go.addEventListener('click', function handleGoClick() {
state.name = views.name.value;
views.info.style.display = 'none';
log('debug', `You id is ${state.id} and your name is ${state.name}`);
loading();
});
}
function loading() {
views.loading.style.display = 'block';
state.peer = new Peer(state.id, {key: '7n632b6iorum1jor'});
state.peer.on('open', function handleOpen() {
views.loading.style.display = 'none';
log('debug', 'Connection opened');
main();
});
}
function main() {
views.ui.style.display = 'block';
state.room.isOwner = state.created;
state.peer.on('connection', handleConnection);
state.peer.on('error', (...args) => log('error', args.join(' ')));
if (!state.created) {
handleConnection(peer.connect(state.roomId, {metadata: {name: state.name}}));
}
views.id.innerHTML = `Invite people to this room with this id: ${state.roomId}`;
}
function handleConnection(conn) {
conn.on('data', handleData(conn));
conn.on('close', handleExit(conn));
conn.on('error', handleExit(conn));
if (!state.created) {
conn.send(message.join());
}
view.send.addEventListener('click', function sendMessage() {
conn.send(message.message(view.message.value));
addMessage({
name: state.name,
text: view.message.value
});
});
}
function handleData(conn) {
return function handleIncomingData(data) {
let val = ({
join() {
state.room.memebers[conn.peer] = conn;
return message.ack(state.room.memebers);
},
message() {
addMessage({
name: conn.metadata.name,
text: data.text
});
updateMessages();
},
ack() {
state.room.members = data.members;
}
}[data.type]());
val&&conn.send(val);
};
}
function handleExit(conn) {
return function handleMemberExit() {
state.room.members[conn.peer] = null;
log('error', 'Error in connection');
};
}
function addMessage(message) {
state.room.messages.push(message);
views.messages.appendChild(document.createElement('li')).innerHTML = `<strong>${message.name}</strong>: ${message.text}`;
}
window.addEventListener('load', function () {
views.$defaults.forEach(v => views[v] = document.getElementById(v));
room();
log('debug', 'window loaded!');
});
} catch (e) {
log('error', `Uncaught ${e.type}: ${e.message}`);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment