index.html 9.94 KB
<!DOCTYPE html>
<html>
	<head>
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<link rel="stylesheet" type="text/css" href="../style.css">
	</head>
	<body>
		<div id="sign" class="hue page">
			<style>
				input, button {
					margin: 1em 0;
					padding: 1em;
				}
				.or {
					display: inline-block;
					width: 15%;
				}
			</style>
			<form id="inup" class="sign pad center">
				<div class="loud">Welcome,</div>
				<div class="mid row col">
					<input name="alias" class="huet jot sap" placeholder="alias">
					Enter your public username.
				</div>
				<div class="mid row col">
					<input name="pass" class="huet jot sap" type="password" placeholder="passphrase">
					And a long private passphrase.
				</div>
				<div class="mid row col go">
					<button class="huet sap act symbol">sign in</button>
					<div class="or">or</div>
					<button class="huet sap act symbol">sign up</button>
				</div>
				<a href="info">more info</a>
			</form>
		</div id="sign">
		
		<div id="people" class="hue2 page">
			<ul name="users" class="pad">
				<h3>Here is a list of people:</h3>
				<li name="#">
					<!-- <h3 name="."></h3> -->
					<ul>
						<a href="person" name="#" class="whitet act">
							<li>
								<span name="who">
									<b name="name"></b>
								</span>
								<i>~</i><i name="alias" class="sort"></i>
								<input name="pub">
							</li>
						</a>
					</ul>
				</li>
			</ul>
		</div id="people">
		
		<div id="converse" class="page">
			<ul>
			</ul>
			<div class="model">
				<li class="msg">
					<span name="fro">Alias</span>: <span name="what"></span>
				</li>
			</div>
			<form>
				<input placeholder="to" name="to">
				<textarea name="what"></textarea>
				<input type="submit" value="submit">
				<div class="status"></div>
			</form>
		</div id="converse">
		
		<div id="person" class="hue3 page">
			<style>
				#person .back {
					position: absolute;
					top: 0.3em;
					left: 0.5em;
					width: 2em;
					height: 2em;
					z-index: 99999;
				}
			</style>
			<a href="people" class="whitet act back">&#8592</a>
			<div class="pad">
				<div name="who">
					<!-- img src="" -->
					<h2 name="name" contenteditable="true">Name</h2>
					<i name="born"></i>
					<span name="bio" contenteditable="true">bio</span>
					<form id="say" class="center none">
						<input class="jot" placeholder="Say something!" style="width: 80%;">
						<input type="submit" id="speak" class="huet2 sap act symbol" style="min-width: 5em; width: 10%;" value="speak">
					</form>
					<div>
						<ul name="said">
							<li name="#" class="sit sort shade rim"><div name="what" class="rim"></div></li>
						</ul>
					</div>
				</div>
				<input name="pub">
			</div>
		</div id="person">

		<div id="info" class="page">
			<p>A mysterious new example app has appeared! It is not finished/ready yet.</p>
		</div id="info">
		
		<div id="tell" class="center">
			<style>
				#tell {
					position: fixed;
					top: 0;
					left: 0;
					right: 0;
					height: 0;
					overflow: visible;
				}
				#tell p {
					top: -2em;
					width: 50%;
					border: solid #222 0.2em;
					border-top: none;
					padding: 1%;
					opacity: 0;
					visibility: hidden;
					transition: visibility 2s, all 1s ease-in;
				}
				#tell .notify {
					top: 0em;
					opacity: 0.8;
					visibility: visible;
					transition: visibility 0s, all 0.25s ease-out;
				}
			</style>
			<p class="mid black">Hello world!</p>
		</div>

		<!-- script src="/Users/mark/Dropbox/Public/gun/db/examples/jquery.js"></script>
		<script src="/Users/mark/Dropbox/Public/gun/db/gun.js"></script>
		<script src="/Users/mark/Dropbox/Public/gun/db/lib/cryptomodules.js"></script>
		<script src="/Users/mark/Dropbox/Public/gun/db/sea.js"></script>
		<script src="/Users/mark/Dropbox/Public/gun/db/as.js"></script -->

		<script src="/jquery.js"></script>
		<script src="/gun.js"></script>
		<script src="/gun/sea.js"></script>
		<script src="/gun/as.js"></script>
		<script src="/gun/nts.js"></script>
		<script>
			// Check out the interactive tutorial
			// for how to build a simplified version
			// of this example: https://scrimba.com/c/c2gBgt4
			var gun = Gun(location.origin+'/gun');
			var app = gun.get('example/contacts/7');
			var user = gun.user();
			var c = window.c = {};
			(function(){
				c.hash = location.hash.slice(1);
				gun.on('auth', function(at){
					if('sign' === c.hash){ c.hash = '' }
					as.route(c.hash || 'people');
				});
				gun.on('secure', function(at){
					/* enforce some rules about shared app level data */
					if(!at.put || !at.put.users){ return }
					var no;
					Gun.node.is(at.put.users, function(val, key){
						Gun.SEA.verify(val, false, function(val){
						//Gun.SEA.read(val, false, function(val){
							if('~@'+key === Gun.val.link.is(val)){ return }
							no = true;
						})
						if(no){ return no }
					});
					if(no){ return }
					this.to.next(at);
				});
				$(document).on('keyup', "form.sign input:first", as.wait(function(){
					/*
					var form = $(this).closest('form'), data = {alias: $(this).val()};
					if(!data.alias || data.alias.length < 5){
						return;
					}
					var exist = gun.path('alias').path(data.alias);
					exist.get(function(at){
						form.find('.or').addClass('none');
						form.find('button:first').toggleClass('none', at.put? false : true);
						form.find('button:last').toggleClass('none', at.put? true : false);
					});
					*/
				})).on('click','form.sign button:last', function(){
					var but = $(this), form = $(this).closest('form'), data = {alias: form.find('input:first').val(), pass: form.find('input:last').val()};
					data.born = Gun.time.is();
					if(!data.alias || data.alias.length < 5){
						c.tell("Alias needs to be longer than 5 characters.");
						return;
					}
					if(!data.pass || data.pass.length < 9){
						c.tell("Passphrase needs to be longer than 9 characters.");
						return;
					}
					but.addClass('pulse');
					data.alias = data.alias.toLowerCase();
					user.create(data.alias, data.pass, function(ack){
						if(!ack.wait){ but.removeClass('pulse') }
						if(ack.err){ c.tell(ack.err); return }
						if(ack.pub){
							gun.get('users').get(data.alias).put(gun.get('~@'+data.alias));
						}
						session(data);
						user.auth(data.alias, data.pass);
					});
				}).on('click','form.sign button:first', become);
				function become(){
					var form = $('#sign').find('form'), data = {alias: form.find('input:first').val(), pass: form.find('input:last').val()};
					data.alias = data.alias || sessionStorage.alias;
					data.pass = data.pass || sessionStorage.tmp;
					if(!data.alias || data.alias.length < 5){
						c.tell("Alias needs to be longer than 5 characters.");
						return;
					}
					if(!data.pass || data.pass.length < 9){
						c.tell("Passphrase needs to be longer than 9 characters.");
						return;
					}
					var but = form.find('button:first');
					but.addClass('pulse');
					data.alias = data.alias.toLowerCase();
					user.auth(data.alias, data.pass, function(ack){
						if(!ack.wait){ but.removeClass('pulse') }
						if(ack.err){ c.tell(ack.err); return }
						session(data);
					});
				}
				if(!location.hash){
					as.route('sign');
				}
				if(!window.sessionStorage){ window.sessionStorage = {clear:function(){}} }
				if(sessionStorage.tmp){
					become();
				}
				function session(data){
					if(!sessionStorage){ return }
					sessionStorage.alias = data.alias;
					sessionStorage.tmp = data.pass;
				}
				c.tell = function(what, n){
					var e = $('#tell').find('p');
					e.addClass('notify').text(what);
					clearTimeout(c.tell.to);
					c.tell.to = setTimeout(function(){e.removeClass('notify')}, n || 2500);
				}
			}());
			(function(){
				$(document).on('submit', '#say', function(e){
					e.preventDefault();
					user.get('who').get('said').set({
						what: $(this).find('.jot').val()
					});
					$(this).find('.jot').val('');
				});
			}());
			as.route.page('sign', function(){
				$(document.forms.inup.alias).focus();
			});
			as.route.page('people', function(){
				if(!user.is){ return as.route('sign') }
				as('#people', gun, function(data, key, el){
					if('pub' !== key){ return }
					el.closest('a').attr('href', '#person/' + data);
				});
			});
			as.route.page('person', function(){
				if(!user.is){ return as.route('sign') }
				var pub = location.hash.split('/').slice(-1)[0];
				(pub === user._.pub? $('#say').show() : $('#say').hide());
				as('#person', window.PUB = gun.get('~'+pub));
			});







			(function(converse){
				as.route.page('converse', function(){
					if(!c.me){ return as.route('sign') }
					converse.lock = false;
					var alias = location.hash.split('/').slice(-1);
					$('#converse form').find('input:first').val(alias);
					function inbox(msg, id){
						if(!sign.verify(msg.pub, msg.what, msg.sig)){ return }
						msg.fro = (msg.to === c.me.alias? alias : c.me.alias);
						as.route.render(id, '.msg', $('#converse ul'), msg);
					}
					sign.is(alias, function(acc){
						sign.is(c.me.alias).path('msgs').path(acc.pub).map(inbox);
					}).path('msgs').path(c.me.pub).map(inbox);
				});
				$(document).on('submit', '#converse form', function(e){
					e.preventDefault();
					if(converse.lock){ return console.log('message sending already') }
					converse.lock = true; // prevent duplicate sends.
					var form = $(this), msg = {};
					msg.to = form.find('input:first').val();
					msg.what = form.find('textarea').val();
					sign.is(msg.to, function(to){
						if(!priv){
							form.find('.status').text("Failed to send. Please sign in again.");
							converse.lock = false;
							return;
						}
						msg.sig = sign.sig(msg.what, priv);
						msg.pub = c.me.pub;
						msg.when = Gun.time.is();
						console.log("sending msg", msg);
						sign.is(c.me.alias).path('msgs').path(to.pub).set(gun.put(msg));
						converse.lock = false;
					}, function(){
						form.attr('disabled', false).find('.status').text(msg.to + " cannot be found! Alias is case sensitive.");
						converse.lock = false;
					});
				});
			}({}));
		//}());</script>
	</body>
</html>