Browse Source

1.1.0 -- refactor to store client data in browser with localforage.js

english
Ev Bogue 4 years ago
parent
commit
a328b91ba5
  1. 451
      app.js
  2. 1
      index.html
  3. 388
      lib.js
  4. 7
      localforage.min.js
  5. 2
      package.json
  6. 10
      server.js

451
app.js

@ -1,18 +1,39 @@
var screen = h('div', {id: 'screen'})
document.body.appendChild(screen)
var keys = getKeys()
localforage.getItem('id', function (err, value) {
// the navbar has a dual purpose of generating a key if you don't already have one
var navbar = h('div', {classList: 'navbar'}, [
h('div', {classList: 'internal'}, [
h('li', [h('a', {href: '/'}, ['Home'])]),
h('li', [h('a', {href: '#' + keys.publicKey}, [getName(keys.publicKey)])]),
h('li', [h('a', {href: '/#key'}, ['Key'])])
])
])
if (value) {
var keys = value
var navbar = h('div', {classList: 'navbar'}, [
h('div', {classList: 'internal'}, [
h('li', [h('a', {href: '/'}, ['Home'])]),
h('li', [h('a', {href: '#' + keys.publicKey}, [getName(keys.publicKey)])]),
h('li', [h('a', {href: '/#key'}, ['Key'])])
])
])
document.body.appendChild(navbar)
} else if (value == null) {
var genkey = nacl.sign.keyPair()
if (genkey) {
var keys = {
publicKey: '@' + nacl.util.encodeBase64(genkey.publicKey),
privateKey: nacl.util.encodeBase64(genkey.secretKey)
}
// when we get our next round of funding, let's figure out how to do this without a page reload
if (keys.publicKey.includes('/')) {
console.log('TRYING AGAIN')
setTimeout(function () {
window.location.reload()
}, 10)
} else {
localforage.setItem('id', keys)
window.location.reload()
}
}
}
})
if (!localStorage['subscribees']) {
var subscribees = ['@218Fd2bCrmXe4gwnMg5Gcb9qVZrjXquym2AlelbkBro=']
@ -24,262 +45,264 @@ if (!localStorage['pubs']) {
localStorage['pubs'] = JSON.stringify(pubs)
}
document.body.appendChild(navbar)
function compose (keys, opts) {
var header = h('div', {classList: 'message'})
var scroller = document.getElementById('scroller')
scroller.insertBefore(header, scroller.firstChild)
localforage.getItem('id', function (err, keys) {
if (keys) {
var header = h('div', {classList: 'message'})
var scroller = document.getElementById('scroller')
scroller.insertBefore(header, scroller.firstChild)
var textarea = h('textarea', {placeholder: 'Write a new bog post'})
header.appendChild(textarea)
var composer = h('div', [
h('button', {
onclick: function () {
if (textarea.value) {
var content = {
author: keys.publicKey,
type: 'post',
text: textarea.value,
timestamp: Date.now()
var textarea = h('textarea', {placeholder: 'Write a new bog post'})
header.appendChild(textarea)
var composer = h('div', [
h('button', {
onclick: function () {
if (textarea.value) {
var content = {
author: keys.publicKey,
type: 'post',
text: textarea.value,
timestamp: Date.now()
}
textarea.value = ''
publish(content, keys)
}
}
textarea.value = ''
publish(content, keys)
}
}
}, ['Publish'])
])
header.appendChild(composer)
}, ['Publish'])
])
header.appendChild(composer)
}
})
}
function route () {
src = window.location.hash.substring(1)
var scroller = h('div', {id: 'scroller'})
var screen = document.getElementById('screen')
localforage.getItem('id', function (err, keys) {
src = window.location.hash.substring(1)
var scroller = h('div', {id: 'scroller'})
var screen = document.getElementById('screen')
screen.appendChild(scroller)
if (src === 'key') {
var keyMessage = h('div', {classList: 'message'})
screen.appendChild(scroller)
keyMessage.appendChild(h('p', {innerHTML: marked('This is your ed25519 public/private keypair. It was generated using [Tweetnacl.js](https://tweetnacl.js.org/#/). Your public key is your identiy when using [Bogbook](http://bogbook.com/), save your key in a safe place so that you can continue to use the same identity.')}))
if (src === 'key') {
var keyMessage = h('div', {classList: 'message'})
// print stringified keypair
keyMessage.appendChild(h('pre', {style: 'width: 80%'}, [h('code', [JSON.stringify(keys)])]))
keyMessage.appendChild(h('p', {innerHTML: marked('This is your ed25519 public/private keypair. It was generated using [Tweetnacl.js](https://tweetnacl.js.org/#/). Your public key is your identiy when using [Bogbook](http://bogbook.com/), save your key in a safe place so that you can continue to use the same identity.')}))
// delete key button
keyMessage.appendChild(h('button', {
onclick: function () {
localStorage['id'] = ''
location.reload()
}
}, ['Delete Key']))
var textarea = h('textarea', {placeholder: 'Import your existing ed25519 keypair'})
keyMessage.appendChild(textarea)
keyMessage.appendChild(h('button', {
onclick: function () {
if (textarea.value) {
localStorage['id'] = textarea.value
location.reload()
// print stringified keypair
keyMessage.appendChild(h('pre', {style: 'width: 80%'}, [h('code', [JSON.stringify(keys)])]))
// delete key button
keyMessage.appendChild(h('button', {
onclick: function () {
localStorage['id'] = ''
location.reload()
}
}
}, ['Import Key']))
}, ['Delete Key']))
scroller.appendChild(keyMessage)
var textarea = h('textarea', {placeholder: 'Import your existing ed25519 keypair'})
keyMessage.appendChild(textarea)
keyMessage.appendChild(h('button', {
onclick: function () {
if (textarea.value) {
localStorage['id'] = textarea.value
location.reload()
}
}
}, ['Import Key']))
var pubMessage = h('div', {classList: 'message'})
scroller.appendChild(keyMessage)
var newPub = h('input', {placeholder: 'Add a new pub. Ex: ws://bogbook.com/'})
var pubMessage = h('div', {classList: 'message'})
var pubs = JSON.parse(localStorage['pubs'])
var newPub = h('input', {placeholder: 'Add a new pub. Ex: ws://bogbook.com/'})
pubMessage.appendChild(h('div', [
h('p', {innerHTML: marked('These are your bogbook pubs. These servers will sync data when you publish a new post, when you subscribe to new feeds, and when you click on feed ids.')}),
newPub,
h('button', {
onclick: function () {
if (newPub.value) {
pubs.push(newPub.value)
localStorage['pubs'] = JSON.stringify(pubs)
location.reload()
var pubs = JSON.parse(localStorage['pubs'])
pubMessage.appendChild(h('div', [
h('p', {innerHTML: marked('These are your bogbook pubs. These servers will sync data when you publish a new post, when you subscribe to new feeds, and when you click on feed ids.')}),
newPub,
h('button', {
onclick: function () {
if (newPub.value) {
pubs.push(newPub.value)
localStorage['pubs'] = JSON.stringify(pubs)
location.reload()
}
}
}
}, ['Add Pub'])
]))
function removeButton (pubName) {
var button = h('button', {
onclick: function () {
console.log('removing' + pubName)
for (var i = pubs.length; i--;) {
if (pubs[i] === pubName) {
pubs.splice(i, 1);
localStorage['pubs'] = JSON.stringify(pubs)
window.location.reload()
}, ['Add Pub'])
]))
function removeButton (pubName) {
var button = h('button', {
onclick: function () {
console.log('removing' + pubName)
for (var i = pubs.length; i--;) {
if (pubs[i] === pubName) {
pubs.splice(i, 1);
localStorage['pubs'] = JSON.stringify(pubs)
window.location.reload()
}
}
}
}
}, ['Remove Pub'])
return button
}, ['Remove Pub'])
return button
}
for (i = 0; i < pubs.length; i++) {
var pubName = pubs[i]
pubMessage.appendChild(h('p', [
pubName,
removeButton(pubName)
]))
}
scroller.appendChild(pubMessage)
}
for (i = 0; i < pubs.length; i++) {
var pubName = pubs[i]
pubMessage.appendChild(h('p', [
pubName,
removeButton(pubName)
]))
}
scroller.appendChild(pubMessage)
}
else if (src[0] === '@') {
var profile = h('div', {classList: 'message'})
scroller.appendChild(profile)
if (src == keys.publicKey) {
var nameInput = h('input', {placeholder: 'Publish a new name'})
else if (src[0] === '@') {
var profile = h('div', {classList: 'message'})
scroller.appendChild(profile)
var namePublisher = h('div',[
nameInput,
h('button', {
onclick: function () {
if (nameInput.value) {
if (src == keys.publicKey) {
var nameInput = h('input', {placeholder: 'Publish a new name'})
var content = {
author: keys.publicKey,
type: 'name',
text: nameInput.value,
timestamp: Date.now()
}
var namePublisher = h('div',[
nameInput,
h('button', {
onclick: function () {
if (nameInput.value) {
publish(content, keys)
}
}
}, ['Publish'])
])
profile.appendChild(namePublisher)
readFile()
var imageInput = h('span', [
h('input', {id: 'inp', type:'file'}),
h('span', {id: 'b64'}),
h('img', {id: 'img'})
])
var imagePublisher = h('div', [
imageInput,
h('button', {
onclick: function () {
var content = {
author: keys.publicKey,
type: 'name',
text: nameInput.value,
type: 'image',
image: document.getElementById("img").src,
timestamp: Date.now()
}
publish(content, keys)
}
}
}, ['Publish'])
])
profile.appendChild(namePublisher)
}, ['Publish'])
])
profile.appendChild(imagePublisher)
document.getElementById("inp").addEventListener("change", readFile);
} else {
var subscribees = JSON.parse(localStorage['subscribees'])
if (subscribees.includes(src)) {
profile.appendChild(h('button', {
onclick: function () {
for (var i = subscribees.length; i--;) {
if (subscribees[i] === src) {
subscribees.splice(i, 1);
localStorage['subscribees'] = JSON.stringify(subscribees)
window.location.reload()
}
}
}
// remove subscribee
}, ['UNSUBSCRIBE']))
} else {
profile.appendChild(h('button', {
onclick: function () {
subscribees.push(src)
localStorage['subscribees'] = JSON.stringify(subscribees)
window.location.reload()
}
}, ['SUBSCRIBE']))
}
}
readFile()
var pubs = JSON.parse(localStorage['pubs'])
var imageInput = h('span', [
h('input', {id: 'inp', type:'file'}),
h('span', {id: 'b64'}),
h('img', {id: 'img'})
])
for (i = 0; i < pubs.length; i++) {
requestFeed(src, pubs[i])
}
localforage.getItem(src, function (err, log) {
if (log) {
for (var i=0; i < log.length; i++) {
var post = log[i]
scroller.appendChild(renderMessage(post))
}
}
})
}
var imagePublisher = h('div', [
imageInput,
h('button', {
onclick: function () {
var content = {
author: keys.publicKey,
type: 'image',
image: document.getElementById("img").src,
timestamp: Date.now()
}
else if (src[0] === '%') {
publish(content, keys)
localforage.getItem('log', function (err, log) {
for (var i = log.length - 1; i >= 0; --i) {
if (log[i].key === src) {
var post = log[i]
scroller.appendChild(renderMessage(post))
}
}, ['Publish'])
])
profile.appendChild(imagePublisher)
}
})
}
document.getElementById("inp").addEventListener("change", readFile);
else {
compose(keys)
} else {
var subscribees = JSON.parse(localStorage['subscribees'])
if (subscribees.includes(src)) {
profile.appendChild(h('button', {
onclick: function () {
for (var i = subscribees.length; i--;) {
if (subscribees[i] === src) {
subscribees.splice(i, 1);
localStorage['subscribees'] = JSON.stringify(subscribees)
window.location.reload()
}
}
}
// remove subscribee
}, ['UNSUBSCRIBE']))
} else {
profile.appendChild(h('button', {
onclick: function () {
subscribees.push(src)
localStorage['subscribees'] = JSON.stringify(subscribees)
window.location.reload()
}
}, ['SUBSCRIBE']))
}
}
var pubs = JSON.parse(localStorage['pubs'])
for (i = 0; i < pubs.length; i++) {
requestFeed(src, pubs[i])
}
if (localStorage[src]) {
var log = JSON.parse(localStorage[src])
for (var i=0; i < log.length; i++) {
var post = log[i]
scroller.appendChild(renderMessage(post))
console.log(subscribees)
for (i = 0; i < subscribees.length; i++) {
var pubs = JSON.parse(localStorage['pubs'])
for (n = 0; n < pubs.length; n++) {
requestFeed(subscribees[i], pubs[n])
}
}
}
}
else if (src[0] === '%') {
if (localStorage['log']) {
var log = JSON.parse(localStorage['log'])
console.log(log.length)
for (var i = log.length - 1; i >= 0; --i) {
if (log[i].key === src) {
localforage.getItem('log', function (err, log) {
for (var i=0; i < log.length; i++) {
var post = log[i]
scroller.appendChild(renderMessage(post))
}
}
}
}
else {
compose(keys)
var subscribees = JSON.parse(localStorage['subscribees'])
console.log(subscribees)
for (i = 0; i < subscribees.length; i++) {
var pubs = JSON.parse(localStorage['pubs'])
for (n = 0; n < pubs.length; n++) {
requestFeed(subscribees[i], pubs[n])
}
}
if (localStorage['log']) {
var log = JSON.parse(localStorage['log'])
for (var i=0; i < log.length; i++) {
var post = log[i]
scroller.appendChild(renderMessage(post))
}
// sort log by timestamp and save over -- I don't know how expensive this is, we probably don't want to do this every single time we load the log?
var newLog = log.sort(function (a, b) {
return b.content.timestamp - a.content.timestamp
var newLog = log.sort(function (a, b) {
return b.content.timestamp - a.content.timestamp
})
if (newLog) {
localforage.setItem('log', log)
}
})
if (newLog) {
localStorage['log'] = JSON.stringify(newLog)
}
}
}
})
}

1
index.html

@ -8,6 +8,7 @@
<body>
<script src="nacl.min.js"></script>
<script src="nacl-util.min.js"></script>
<script src="localforage.min.js"></script>
<script src="marked.min.js"></script>
<script src="lib.js"></script>
<script src="app.js"></script>

388
lib.js

@ -1,135 +1,193 @@
// generate a public.private keypair with TweetNaCl.js
function getKeys () {
if (localStorage['id']) {
var keys = JSON.parse(localStorage['id'])
return keys
} else {
var genkey = nacl.sign.keyPair()
if (genkey) {
var keys = {
publicKey: '@' + nacl.util.encodeBase64(genkey.publicKey),
privateKey: nacl.util.encodeBase64(genkey.secretKey),
localforage.getItem('id', function(err, value) {
if (value) {
var keys = value
return keys
} else if (value == null) {
var genkey = nacl.sign.keyPair()
if (genkey) {
var keys = {
publicKey: '@' + nacl.util.encodeBase64(genkey.publicKey),
privateKey: nacl.util.encodeBase64(genkey.secretKey)
}
// when we get our next round of funding, let's figure out how to do this without a page reload
if (keys.publicKey.includes('/')) {
console.log('TRYING AGAIN')
setTimeout(function () {
window.location.reload()
}, 10)
} else {
localforage.setItem('id', keys)
return keys
}
}
}
})
return keys
}
console.log(genkey)
function requestFeed (src, server) {
var ws = new WebSocket(server + src)
// for some reason keys with /'s in them mess up node, so we'll try generating keys again if they contain slashes
if (keys.publicKey.includes('/')) {
console.log('TRYING AGAIN')
setTimeout(function () {
window.location.reload()
}, 10)
} else {
localStorage['id'] = JSON.stringify(keys)
return keys
localforage.getItem(src, function (err, log) {
if (log) {
// update the log
console.log('LOG DOES EXIST, asking')
ws.onopen = function () {
// req feed
var clientLog = {
publicKey: src,
log: log
}
console.log(clientLog)
ws.send(JSON.stringify(clientLog))
}
ws.onmessage = function (ev) {
console.log(ev.data)
var serverLog = JSON.parse(ev.data)
if (serverLog.log.length > log.length) {
// update the log of the id
localforage.setItem(src, serverLog.log)
// concat new items from the log onto the client's public log
localforage.getItem('log', function (err, feed) {
if (feed) {
var num = serverLog.log.length - log.length
var diff = serverLog.log.slice(0, num)
oldLog = feed
newLog = diff.concat(oldLog)
localforage.setItem('log', newLog)
}
})
}
}
} else {
ws.onopen = function () {
// req feed
var clientLog = {
publicKey: src,
log: []
}
ws.send(JSON.stringify(clientLog))
}
// request the log (because we don't have it)
console.log('LOG DOES NOT EXIST, asking')
ws.onmessage = function (ev) {
serverLog = JSON.parse(ev.data)
localforage.setItem(src, serverLog.log)
// concat new items from the log onto the client's public log
localforage.getItem('log', function (err, feed) {
if (feed) {
newLog = serverLog.log.concat(feed)
localforage.setItem('log', newLog)
} else {
localforage.setItem('log', serverLog.log)
}
})
}
}
}
})
}
function requestFeed (src, server) {
var ws = new WebSocket(server + src)
// publish new messages to your log
function publish (content, keys) {
var clientLog = {
publicKey: src
}
console.log(content)
console.log(keys)
localforage.getItem(keys.publicKey, function (err, log) {
if (log) {
var lastPost = log[0]
var seq = lastPost.content.sequence
content.sequence = ++seq
content.previous = nacl.util.encodeBase64(nacl.hash(nacl.util.decodeUTF8(JSON.stringify(log[0]))))
if (localStorage[src]) {
clientLog.log = JSON.parse(localStorage[src])
} else {
clientLog.log = []
}
var post = {
content: content,
signature: nacl.util.encodeBase64(nacl.sign(nacl.util.decodeUTF8(JSON.stringify(content)), nacl.util.decodeBase64(keys.privateKey)))
}
ws.onopen = function () {
ws.send(JSON.stringify(clientLog))
}
// add key (which is a hash of the stringified object post)
post.key = '%' + nacl.util.encodeBase64(nacl.hash(nacl.util.decodeUTF8(JSON.stringify(post))))
ws.onmessage = function (ev) {
var serverData = JSON.parse(ev.data)
if (serverData.log.length > clientLog.log.length) {
// update the log
updateLog(keys.publicKey, post)
// update the log of the id
localStorage[src] = JSON.stringify(serverData.log)
var pubs = JSON.parse(localStorage['pubs'])
// contact new items from the log onto the client's log of everything
var num = serverData.log.length - clientLog.log.length
var diff = serverData.log.slice(0, num)
for (i = 0; i < pubs.length; i++) {
requestFeed(keys.publicKey, pubs[i])
}
if (localStorage['log']) {
var oldLog = JSON.parse(localStorage['log'])
var scroller = document.getElementById('scroller')
if (scroller.firstChild) {
scroller.insertBefore(renderMessage(post), scroller.childNodes[1])
} else {
var oldLog = []
scroller.appendChild(renderMessage(post))
}
var newLog = diff.concat(oldLog)
localStorage['log'] = JSON.stringify(newLog)
location.reload()
}
}
}
// publish new messages to your log
function publish (content, keys) {
} else {
content.sequence = 0
var post = {
content: content,
signature: nacl.util.encodeBase64(nacl.sign(nacl.util.decodeUTF8(JSON.stringify(content)), nacl.util.decodeBase64(keys.privateKey)))
}
if (localStorage[keys.publicKey]) {
var log = JSON.parse(localStorage[keys.publicKey])
var lastPost = log[0]
var seq = lastPost.content.sequence
content.sequence = ++seq
content.previous = nacl.util.encodeBase64(nacl.hash(nacl.util.decodeUTF8(JSON.stringify(log[0]))))
console.log(content.previous)
} else {
console.log('SEQUENCE 0')
content.sequence = 0
}
// add key (which is a hash of the stringified object post)
post.key = '%' + nacl.util.encodeBase64(nacl.hash(nacl.util.decodeUTF8(JSON.stringify(post))))
var post = {
content: content,
signature: nacl.util.encodeBase64(nacl.sign(nacl.util.decodeUTF8(JSON.stringify(content)), nacl.util.decodeBase64(keys.privateKey)))
}
// update the log
updateLog(keys.publicKey, post)
// add key (which is a hash of the stringified object post)
post.key = '%' + nacl.util.encodeBase64(nacl.hash(nacl.util.decodeUTF8(JSON.stringify(post))))
var pubs = JSON.parse(localStorage['pubs'])
// update the log
updateLog(keys.publicKey, post)
var pubs = JSON.parse(localStorage['pubs'])
for (i = 0; i < pubs.length; i++) {
requestFeed(keys.publicKey, pubs[i])
}
for (i = 0; i < pubs.length; i++) {
requestFeed(keys.publicKey, pubs[i])
}
var scroller = document.getElementById('scroller')
if (scroller.firstChild) {
scroller.insertBefore(renderMessage(post), scroller.childNodes[1])
} else {
scroller.appendChild(renderMessage(post))
}
var scroller = document.getElementById('scroller')
if (scroller.firstChild) {
scroller.insertBefore(renderMessage(post), scroller.childNodes[1])
} else {
scroller.appendChild(renderMessage(post))
}
}
})
}
// update your log in the browser
function updateLog (feed, post) {
if (localStorage[feed]) {
var log = JSON.parse(localStorage[feed])
log.unshift(post)
localStorage[feed] = JSON.stringify(log)
} else {
var log = [post]
localStorage[feed] = JSON.stringify(log)
}
console.log('UPDATE LOG')
console.log(feed)
console.log(post)
localforage.getItem(feed, function (err, log) {
if (log) {
log.unshift(post)
localforage.setItem(feed, log)
} else {
log = []
log.unshift(post)
localforage.setItem(feed, log)
}
})
if (localStorage['log']) {
var log = JSON.parse(localStorage['log'])
log.unshift(post)
localStorage['log'] = JSON.stringify(log)
} else {
var log = [post]
localStorage['log'] = JSON.stringify(log)
}
localforage.getItem('log', function (err, log) {
if (log) {
log.unshift(post)
localforage.setItem('log', log)
} else {
log = []
log.unshift(post)
localforage.setItem('log', log)
}
})
}
// file uploaders for user images
@ -181,23 +239,22 @@ function renderMessage (post) {
if (post.content.type == 'post') {
var log = JSON.parse(localStorage['log'])
setTimeout(function () {
for (var i = log.length - 1; i >= 0; --i) {
//console.log(i)
if (log[i].content.reply == post.key) {
var nextPost = log[i]
console.log(nextPost)
var messageExists = (document.getElementById(nextPost.key) !== null);
if (!messageExists) {
messageDiv.appendChild(h('div', {classList: 'submessage'}, [
renderMessage(nextPost)
]))
localforage.getItem('log', function (err, log) {
if (log) {
for (var i = log.length - 1; i >= 0; --i) {
if (log[i].content.reply == post.key) {
var nextPost = log[i]
var messageExists = (document.getElementById(nextPost.key) !== null);
if (!messageExists) {
messageDiv.appendChild(h('div', {classList: 'submessage'}, [
renderMessage(nextPost)
]))
}
}
}
}
}, 10)
})
var renderer = new marked.Renderer();
renderer.link = function(href, title, text) {
if ((href[0] == '@') || (href[0] == '%')) {
@ -222,7 +279,6 @@ function renderMessage (post) {
message.appendChild(h('div', {innerHTML: marked(post.content.text)}))
message.appendChild(h('span', {id: post.key + 'src', classList: 'right'}, [
h('a', {
onclick: function () {
@ -235,37 +291,41 @@ function renderMessage (post) {
var gotName = getName(post.content.author)
var publishButton = h('button', {
onclick: function () {
if (textarea.value) {
var content = {
author: keys.publicKey,
type: 'post',
text: textarea.value,
reply: post.key,
timestamp: Date.now()
localforage.getItem('id', function (err, keys) {
var publishButton = h('button', {
onclick: function () {
if (textarea.value) {
var content = {
author: keys.publicKey,
type: 'post',
text: textarea.value,
reply: post.key,
timestamp: Date.now()
}
publish(content, keys)
message.removeChild(textarea)
message.removeChild(publishButton)
}
console.log(content)
publish(content, keys)
message.removeChild(textarea)
message.removeChild(publishButton)
}
}
}, ['Publish'])
}, ['Publish'])
var textarea = h('textarea', {placeholder: 'Reply to this bog post'}, ['['+ gotName.textContent + '](' + post.content.author + ')'])
var replyButton = h('button', {
classList: 'replyButton:' + post.key,
onclick: function () {
message.removeChild(replyButton)
message.appendChild(textarea)
message.appendChild(publishButton)
}
}, ['Reply'])
var textarea = h('textarea', {placeholder: 'Reply to this bog post'}, ['['+ gotName.textContent + '](' + post.content.author + ')'])
var replyButton = h('button', {
classList: 'replyButton:' + post.key,
onclick: function () {
message.removeChild(replyButton)
message.appendChild(textarea)
message.appendChild(publishButton)
}
}, ['Reply'])
message.appendChild(replyButton)
})
message.appendChild(replyButton)
messageDiv.appendChild(message)
}
@ -274,34 +334,40 @@ function renderMessage (post) {
function getImage (id) {
var image = h('img', {classList: 'small'})
if (localStorage[id]) {
var log = JSON.parse(localStorage[id])
for (var i=0; i < log.length; i++) {
var imagePost = log[i]
if (imagePost.content.type == 'image') {
image = h('img', {classList: 'small', src: imagePost.content.image})
return image
}
var image = h('span')
//image.appendChild(h('img', {classList: 'small'}))
localforage.getItem(id, function (err, log) {
if (log) {
for (var i=0; i < log.length; i++) {
var imagePost = log[i]
if (imagePost.content.type == 'image') {
image.appendChild(h('img', {classList: 'small', src: imagePost.content.image}))
return
}
}
}
}
})
return image
}
function getName (id) {
var name = h('span', [id.substring(0, 10) + '...'])
if (localStorage[id]) {
var log = JSON.parse(localStorage[id])
for (var i=0; i < log.length; i++) {
var namePost = log[i]
if (namePost.content.type == 'name') {
name = h('span', ['@' + namePost.content.text])
return name
var name = h('span')
name.textContent = id.substring(0, 10) + '...'
localforage.getItem(id, function (err, log) {
if (log) {
for (var i=0; i < log.length; i++) {
var namePost = log[i]
if (namePost.content.type == 'name') {
name.textContent = '@' + namePost.content.text
//return name
}
}
}
}
})
return name
}

7
localforage.min.js vendored

File diff suppressed because one or more lines are too long

2
package.json

@ -1,6 +1,6 @@
{
"name": "bogbook",
"version": "1.0.0",
"version": "1.1.0",
"description": "secure blockchain logging (blogging, without the l) -- bogging",
"main": "server.js",
"scripts": {

10
server.js

@ -9,7 +9,7 @@ http.createServer(
).listen(8089)
opn('http://localhost:8089')
//opn('http://localhost:8089')
// websocket server (8080)
@ -36,24 +36,24 @@ wss.on('connection', function (ws) {
log: serverLog
}
ws.send(JSON.stringify(sendingLog))
console.log('SENT ' + publicKey + ' TO CLIENT')
console.log('SENT ' + publicKey)
}
// if server log has less entries than the log sent by the client, write it to the server
if (serverLog.length < clientLog.length) {
fs.writeFile(__dirname + '/bogs/' + publicKey, JSON.stringify(clientLog), function (err) {
if (err) throw err
console.log('SAVED ' + publicKey + ' TO SERVER')
console.log('SAVED ' + publicKey)
})
}
// if logs are identical, do nothing
if (serverLog.length == clientLog.length) {
console.log(publicKey + ': LOGS ARE THE SAME')
console.log('SAME ' + publicKey)
}
// if log doesn't already exist, write it
} else {
fs.writeFile(__dirname + '/bogs/' + publicKey, JSON.stringify(clientLog), function (err) {
if (err) throw err
console.log('SAVED ' + publicKey + ' TO SERVER')
console.log('SAVED ' + publicKey)
})
}
}

Loading…
Cancel
Save