building iris chat example

This commit is contained in:
Martti Malmi 2020-01-08 21:51:12 +02:00
parent 14ebd73d80
commit 10ed54512a
4 changed files with 15228 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,149 @@
<!DOCTYPE html>
<html>
<head>
<title>Iris Chat</title>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="shortcut icon" href="./favicon.ico">
</head>
<body>
<div class="chat">
<section class="sidebar">
<div class="user-info">
Your public key:
<div class="user-name"></div>
</div>
<div class="chat-list">
<div class="chat-item">
<input type="button" value="+ New chat">
</div>
</div>
</section>
<section class="main">
<div class="online-user-list"></div>
<div class="message-list">Select or create chat to start messaging</div>
<div class="typing-indicator">typing-indicator</div>
<div class="message-form">
<form>
<input id="newMsg" type="text" placeholder="Type a message">
<button>send</button>
</form>
</div>
</section>
</div>
<script src="/jquery.js"></script>
<script src="/gun.js"></script>
<script src="/gun/sea.js"></script>
<script src="/gun/nts.js"></script>
<script src="./irisLib.js"></script>
<script>
var gun = Gun([location.origin + '/gun', 'https://gun-us.herokuapp.com/gun']);
var chat = gun.get('converse/' + location.hash.slice(1));
var chats = {};
var keyPromise = new Promise(resolve => {
var pair = localStorage.getItem('chatKeyPair');
if (pair) {
resolve(JSON.parse(pair));
} else {
Gun.SEA.pair(pair => {
localStorage.setItem('chatKeyPair', JSON.stringify(pair));
resolve(pair);
})
}
});
var key;
keyPromise.then(k => {
key = k;
gun.user().auth(key);
$(".user-name").text(key.pub);
irisLib.Chat.getChats(gun, key, chatReceived);
});
function chatReceived(pub) {
if (!pub || Object.prototype.hasOwnProperty.call(chats, pub)) {
return;
}
console.log(pub);
var el = $('<div class="chat-item">' + pub.slice(0, 8) + '...</div>');
el.click(() => {
$(".online-user-list").text(pub);
$(".message-list").empty();
var msgs = Object.values(chats[pub].messages);
msgs.forEach(msg => {
var name = msg.selfAuthored ? 'you: ' : 'them: ';
var el = $(
'<div class="msg"><div class="text">' + msg.text + '</div><div class="time">' +
msg.time + '</div></div>'
);
el.toggleClass('our', msg.selfAuthored ? true : false);
$(".message-list").append(el);
});
});
$(".chat-list").append(el);
chats[pub] = new irisLib.Chat({gun, key, participants: pub, onMessage: (msg, info) => {
chats[pub].messages = chats[pub].messages || [];
msg.selfAuthored = info.selfAuthored;
chats[pub].messages[msg.time] = msg;
console.log(msg);
}});
}
$(".chat__submit").on('click', submit);
$(".chat_form").on('keydown', enter);
function enter(e) {
if (e.which !== 13) { return }
submit(e);
}
function submit(e) {
e.preventDefault();
var msg = { when: Gun.time.is() };
msg.who = $('.chat__name-input').val();
if (!msg.who) {
msg.who = 'user' + Gun.text.random(3);
$('.chat__name-input').val(msg.who);
}
msg.what = $('.chat__message-input').val();
if (!msg.what) { return }
chat.set(msg);
$('.chat__message-input').val('').focus();
}
chat.map().val(function (msg, id) {
if (!msg) { return }
var messageList = $('.chat__message-list');
var last = sort(msg.when, messageList.children('li').last());
var li = $("#msg-" + id)[0]; // grab if exists
if (!li) {
li = $('.model li').clone(true) // else create it
.attr('id', 'msg-' + id)
.insertAfter(last);
}
// bind the message data into the UI
li = $(li);
li.find('.chat__name').text(msg.who);
li.find('.chat__message-text').text(msg.what);
li.find('.sort').text(msg.when);
var time = new Date(msg.when);
li.find('.chat__when').text(time.toDateString() + ', ' + time.toLocaleTimeString());
$('html, body').stop(true, true)
.animate({ scrollTop: messageList.height() });
});
function sort(num, li) { return parseFloat(num) >= parseFloat($(li).find('.sort').text() || -Infinity) ? li : sort(num, li.prev()) }
</script>
</body>
</html>

14958
examples/iris-chat/irisLib.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,121 @@
body {
font-size: 15px;
color: #262626;
font-family: "SF Pro Text", "SF Pro Icons", system, -apple-system, system-ui, system-ui, "Helvetica Neue", Helvetica, "Lucida Grande", sans-serif;
padding: 0;
margin: 0;
}
.chat {
display: flex;
flex-direction: row;
height: 100vh;
background-color: white;
}
.sidebar {
overflow-x: hidden;
display: flex;
flex-direction: column;
flex: 1 0 10em;
border-right: 1px solid #dfdfdf;
}
.main {
display: flex;
flex-direction: column;
flex: 10 0 10em;
}
/*----- Main------- */
.online-user-list {
flex:1;
background-color: #efefef;
max-height:50px;
padding: 10px;
font-size: 12px;
}
.message-list {
flex:1;
overflow-y: scroll;
padding: 10px;
background-color: #e5ddd5;
}
.msg {
background-color: #ffffff;
margin: 0 40px 10px 0;
padding: 10px;
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.1);
border-radius: 10px;
}
.msg.our {
text-align: right;
background-color: #d7f7c5;
border-radius: 10px 0px 10px 10px;
margin: 0 0px 10px 40px;
}
.msg .time {
text-align: right;
font-size: 12px;
color: rgba(0, 0, 0, 0.45);
}
.typing-indicator {
flex:1;
max-height:30px;
background-color: #ccc;
padding: 10px;
}
.message-form {
flex:1;
flex-direction: row;
max-height:70px;
background-color: #efefef;
padding: 10px;
}
.message-form input {
flex: 5;
width: auto;
}
.message-form button {
flex: 1;
}
/*----- Sidebar------- */
.user-info {
flex:1;
max-height:50px;
overflow-y: hidden;
overflow-x: wrap;
padding: 10px;
background-color: #efefef;
}
.user-name {
font-size: 12px;
}
.chat-list{
flex:1;
overflow-y: scroll;
}
.chat-item {
padding: 20px 10px;
overflow-x: hidden;
border-bottom: 1px solid #efefef;
cursor: pointer;
}
.chat-item:hover {
background: #f3f3f3;
}