From 3be83699db9f8e3b3c5e53d492a655813d163614 Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Fri, 6 Sep 2019 00:18:25 -0500 Subject: [PATCH] boards now load async --- .../default-plugins/flow/flowapi.py | 26 ++++- .../default-plugins/flow/info.json | 9 +- onionr/static-data/default_config.json | 2 +- onionr/static-data/www/board/autorefresh.js | 4 +- onionr/static-data/www/board/board.js | 102 +++++++++++++++--- onionr/static-data/www/board/index.html | 6 +- requirements-notifications.in | 1 + requirements-notifications.txt | 8 ++ requirements.in | 1 - 9 files changed, 130 insertions(+), 29 deletions(-) create mode 100644 requirements-notifications.in create mode 100644 requirements-notifications.txt diff --git a/onionr/static-data/default-plugins/flow/flowapi.py b/onionr/static-data/default-plugins/flow/flowapi.py index 704e3b27..3d97abba 100755 --- a/onionr/static-data/default-plugins/flow/flowapi.py +++ b/onionr/static-data/default-plugins/flow/flowapi.py @@ -17,12 +17,18 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ''' +import json +import os from flask import Response, request, redirect, Blueprint, abort from utils import identifyhome import deadsimplekv as simplekv flask_blueprint = Blueprint('flow', __name__) +with open(os.path.dirname(os.path.realpath(__file__)) + '/info.json', 'r') as info_file: + data = info_file.read().strip() + version = json.loads(data, strict=False)['version'] + @flask_blueprint.route('/flow/getpostsbyboard/') def get_post_by_board(board): board_cache = simplekv.DeadSimpleKV(identifyhome.identify_home() + '/board-index.cache.json', flush_on_exit=False) @@ -32,4 +38,22 @@ def get_post_by_board(board): posts = '' else: posts = ','.join(posts) - return Response(posts) \ No newline at end of file + return Response(posts) + +@flask_blueprint.route('/flow/getpostsbyboard//') +def get_post_by_board_with_offset(board, offset): + offset = int(offset) + OFFSET_COUNT = 10 + board_cache = simplekv.DeadSimpleKV(identifyhome.identify_home() + '/board-index.cache.json', flush_on_exit=False) + board_cache.refresh() + posts = board_cache.get(board) + if posts is None: + posts = '' + else: + posts.reverse() + posts = ','.join(posts[offset:offset + OFFSET_COUNT]) + return Response(posts) + +@flask_blueprint.route('/flow/version') +def get_version(): + return Response(version) diff --git a/onionr/static-data/default-plugins/flow/info.json b/onionr/static-data/default-plugins/flow/info.json index 993339f1..d8b98bb5 100755 --- a/onionr/static-data/default-plugins/flow/info.json +++ b/onionr/static-data/default-plugins/flow/info.json @@ -1,5 +1,4 @@ -{ - "name" : "flow", - "version" : "1.0", - "author" : "onionr" -} +{ "name": "flow", + "version": "0.0.1", + "author": "onionr" +} \ No newline at end of file diff --git a/onionr/static-data/default_config.json b/onionr/static-data/default_config.json index 565b5f59..6f96bbf1 100755 --- a/onionr/static-data/default_config.json +++ b/onionr/static-data/default_config.json @@ -85,6 +85,6 @@ "timers" : { "lookupBlocks" : 25, - "getBlocks" : 30 + "getBlocks" : 10 } } diff --git a/onionr/static-data/www/board/autorefresh.js b/onionr/static-data/www/board/autorefresh.js index c4f270c4..d68ada23 100644 --- a/onionr/static-data/www/board/autorefresh.js +++ b/onionr/static-data/www/board/autorefresh.js @@ -6,14 +6,14 @@ function autoRefresh(){ function setupInterval(){ if (checkbox.checked){ - refreshInterval = setInterval(autoRefresh, 10000) + refreshInterval = setInterval(autoRefresh, 3000) autoRefresh() return } clearInterval(refreshInterval) } -var refreshInterval = setInterval(autoRefresh, 10000) +var refreshInterval = setInterval(autoRefresh, 3000) setupInterval() checkbox.onchange = function(){setupInterval} \ No newline at end of file diff --git a/onionr/static-data/www/board/board.js b/onionr/static-data/www/board/board.js index 8520168a..1f70b8fc 100755 --- a/onionr/static-data/www/board/board.js +++ b/onionr/static-data/www/board/board.js @@ -24,16 +24,42 @@ webpassword = webpass newPostForm = document.getElementById('addMsg') firstLoad = true lastLoadedBoard = 'global' +loadingMessage = document.getElementById('loadingBoard') -function appendMessages(msg){ +let toggleLoadingMessage = function(){ + switch (loadingMessage.style.display){ + case "block": + case "inline": + case "inline-block": + loadingMessage.style.display = "none" + break; + default: + loadingMessage.style.display = "initial" + break; + } +} + +fetch('/flow/version', { + method: 'GET', + headers: { + "token": webpass + }}) +.then((resp) => resp.text()) // Transform the data into json +.then(function(data) { + document.getElementById('circlesVersion').innerText = data +}) + +function appendMessages(msg, blockHash, beforeHash){ var humanDate = new Date(0) if (msg.length == 0){ return } - var msg = JSON.parse(msg) - var dateEl = document.createElement('div') + //var msg = JSON.parse(msg) var el = document.createElement('div') var msgDate = msg['meta']['time'] + var feed = document.getElementById("feed") + var beforeEl = null + if (msgDate === undefined){ msgDate = 'unknown' } @@ -43,6 +69,13 @@ function appendMessages(msg){ } el.className = 'entry' el.innerText = msg['content'] + if (beforeHash !== null){ + for (x = 0; x < feed.children.length; x++){ + if (feed.children[x].getAttribute('data-bl') === beforeHash){ + beforeEl = feed.children[x] + } + } + } /* Template Test */ // Test to see if the browser supports the HTML template element by checking @@ -54,9 +87,10 @@ function appendMessages(msg){ var template = document.getElementById('cMsgTemplate') // Clone the new row and insert it into the table - var feed = document.getElementById("feed") - var clone = document.importNode(template.content, true); + var clone = document.importNode(template.content, true) var div = clone.querySelectorAll("div") + + div[0].setAttribute('data-bl', blockHash) div[2].textContent = msg['content'] if (typeof msg['meta']['signer'] != 'undefined'){ div[3].textContent = msg['meta']['signer'].substr(0, 5) @@ -64,16 +98,23 @@ function appendMessages(msg){ } div[4].textContent = msgDate + loadingMessage.style.display = "none" if (firstLoad){ - feed.appendChild(clone) + //feed.appendChild(clone) + feed.prepend(clone) + firstLoad = false } else{ - feed.prepend(clone) + if (beforeEl === null){ + feed.prepend(clone) + } + else{ + //feed.insertAfter(clone, beforeEl) + beforeEl.insertAdjacentElement("beforebegin", clone) + } + } - } else { - // Find another way to add the rows to the table because - // the HTML template element is not supported. } } @@ -81,6 +122,7 @@ function getBlocks(){ var feed = document.getElementById("feed") var ch = document.getElementById('feedIDInput').value if (lastLoadedBoard !== ch){ + toggleLoadingMessage() while (feed.firstChild) { feed.removeChild(feed.firstChild); } @@ -92,23 +134,49 @@ function getBlocks(){ document.getElementById('none').remove(); } + var feedText = httpGet('/flow/getpostsbyboard/' + ch) - var blockList = feedText.split(',').reverse() + var blockList = feedText.split(',') for (i = 0; i < blockList.length; i++){ - while (blockList[i].length < 64) blockList[i] = "0" + blockList[i] + while (blockList[i].length < 64) { blockList[i] = "0" + blockList[i] } if (! requested.includes(blockList[i])){ if (blockList[i].length == 0){ continue } - bl = httpGet('/getblockdata/' + blockList[i]) - appendMessages(bl) requested.push(blockList[i]) - } + loadMessage(blockList[i], blockList, i) + } } - firstLoad = false } +function loadMessage(blockHash, blockList, count){ + fetch('/getblockdata/' + blockHash, { + method: 'GET', + headers: { + "token": webpass + }}) + .then((resp) => resp.json()) + .then(function(data) { + let before = blockList[count - 1] + let delay = 2000 + if (typeof before == "undefined"){ + before = null + } + else{ + let existing = document.getElementsByClassName('cMsgBox') + for (x = 0; x < existing.length; x++){ + if (existing[x].getAttribute('data-bl') === before){ + delay = 0 + } + } + } + setTimeout(function(){appendMessages(data, blockHash, before)}, delay) + //appendMessages(data, blockHash, before) + }) +} + + document.getElementById('refreshFeed').onclick = function(){ getBlocks() } @@ -140,7 +208,7 @@ newPostForm.onsubmit = function(){ PNotify.success({ text: "Message queued for posting" }) - setTimeout(function(){getBlocks()}, 3000) + setTimeout(function(){getBlocks()}, 500) }) return false } \ No newline at end of file diff --git a/onionr/static-data/www/board/index.html b/onionr/static-data/www/board/index.html index f5310add..d52329ed 100755 --- a/onionr/static-data/www/board/index.html +++ b/onionr/static-data/www/board/index.html @@ -10,6 +10,7 @@ + @@ -54,10 +55,10 @@

- Circles + Circles v

- Anonymous message board + Anonymous message boards

@@ -122,6 +123,7 @@
+ Loading board...
None yet, try refreshing 😃 diff --git a/requirements-notifications.in b/requirements-notifications.in new file mode 100644 index 00000000..3f3a4b23 --- /dev/null +++ b/requirements-notifications.in @@ -0,0 +1 @@ +simplenotifications==0.2.18 diff --git a/requirements-notifications.txt b/requirements-notifications.txt new file mode 100644 index 00000000..f31768f5 --- /dev/null +++ b/requirements-notifications.txt @@ -0,0 +1,8 @@ +# +# This file is autogenerated by pip-compile +# To update, run: +# +# pip-compile --generate-hashes --output-file=requirements-notifications.txt requirements-notifications.in +# +simplenotifications==0.2.18 \ + --hash=sha256:b7efd3d834b1922a3279287913d87fe4ef6fad181ca7edf54bfb8f1d973941e0 diff --git a/requirements.in b/requirements.in index 66c32ad1..28aae67c 100644 --- a/requirements.in +++ b/requirements.in @@ -10,4 +10,3 @@ unpaddedbase32==0.1.0 streamedrequests==1.0.0 jinja2==2.10.1 toomanyobjs==1.1.0 -simplenotifications==0.2.18