boards now load async

master
Kevin Froman 2019-09-06 00:18:25 -05:00
parent 6a0913c437
commit 3be83699db
9 changed files with 130 additions and 29 deletions

View File

@ -17,12 +17,18 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' '''
import json
import os
from flask import Response, request, redirect, Blueprint, abort from flask import Response, request, redirect, Blueprint, abort
from utils import identifyhome from utils import identifyhome
import deadsimplekv as simplekv import deadsimplekv as simplekv
flask_blueprint = Blueprint('flow', __name__) 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/<board>') @flask_blueprint.route('/flow/getpostsbyboard/<board>')
def get_post_by_board(board): def get_post_by_board(board):
board_cache = simplekv.DeadSimpleKV(identifyhome.identify_home() + '/board-index.cache.json', flush_on_exit=False) 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 = '' posts = ''
else: else:
posts = ','.join(posts) posts = ','.join(posts)
return Response(posts) return Response(posts)
@flask_blueprint.route('/flow/getpostsbyboard/<board>/<offset>')
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)

View File

@ -1,5 +1,4 @@
{ { "name": "flow",
"name" : "flow", "version": "0.0.1",
"version" : "1.0", "author": "onionr"
"author" : "onionr" }
}

View File

@ -85,6 +85,6 @@
"timers" : { "timers" : {
"lookupBlocks" : 25, "lookupBlocks" : 25,
"getBlocks" : 30 "getBlocks" : 10
} }
} }

View File

@ -6,14 +6,14 @@ function autoRefresh(){
function setupInterval(){ function setupInterval(){
if (checkbox.checked){ if (checkbox.checked){
refreshInterval = setInterval(autoRefresh, 10000) refreshInterval = setInterval(autoRefresh, 3000)
autoRefresh() autoRefresh()
return return
} }
clearInterval(refreshInterval) clearInterval(refreshInterval)
} }
var refreshInterval = setInterval(autoRefresh, 10000) var refreshInterval = setInterval(autoRefresh, 3000)
setupInterval() setupInterval()
checkbox.onchange = function(){setupInterval} checkbox.onchange = function(){setupInterval}

View File

@ -24,16 +24,42 @@ webpassword = webpass
newPostForm = document.getElementById('addMsg') newPostForm = document.getElementById('addMsg')
firstLoad = true firstLoad = true
lastLoadedBoard = 'global' 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) var humanDate = new Date(0)
if (msg.length == 0){ if (msg.length == 0){
return return
} }
var msg = JSON.parse(msg) //var msg = JSON.parse(msg)
var dateEl = document.createElement('div')
var el = document.createElement('div') var el = document.createElement('div')
var msgDate = msg['meta']['time'] var msgDate = msg['meta']['time']
var feed = document.getElementById("feed")
var beforeEl = null
if (msgDate === undefined){ if (msgDate === undefined){
msgDate = 'unknown' msgDate = 'unknown'
} }
@ -43,6 +69,13 @@ function appendMessages(msg){
} }
el.className = 'entry' el.className = 'entry'
el.innerText = msg['content'] 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 */ /* Template Test */
// Test to see if the browser supports the HTML template element by checking // 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') var template = document.getElementById('cMsgTemplate')
// Clone the new row and insert it into the table // 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") var div = clone.querySelectorAll("div")
div[0].setAttribute('data-bl', blockHash)
div[2].textContent = msg['content'] div[2].textContent = msg['content']
if (typeof msg['meta']['signer'] != 'undefined'){ if (typeof msg['meta']['signer'] != 'undefined'){
div[3].textContent = msg['meta']['signer'].substr(0, 5) div[3].textContent = msg['meta']['signer'].substr(0, 5)
@ -64,16 +98,23 @@ function appendMessages(msg){
} }
div[4].textContent = msgDate div[4].textContent = msgDate
loadingMessage.style.display = "none"
if (firstLoad){ if (firstLoad){
feed.appendChild(clone) //feed.appendChild(clone)
feed.prepend(clone)
firstLoad = false
} }
else{ 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 feed = document.getElementById("feed")
var ch = document.getElementById('feedIDInput').value var ch = document.getElementById('feedIDInput').value
if (lastLoadedBoard !== ch){ if (lastLoadedBoard !== ch){
toggleLoadingMessage()
while (feed.firstChild) { while (feed.firstChild) {
feed.removeChild(feed.firstChild); feed.removeChild(feed.firstChild);
} }
@ -92,23 +134,49 @@ function getBlocks(){
document.getElementById('none').remove(); document.getElementById('none').remove();
} }
var feedText = httpGet('/flow/getpostsbyboard/' + ch) var feedText = httpGet('/flow/getpostsbyboard/' + ch)
var blockList = feedText.split(',').reverse() var blockList = feedText.split(',')
for (i = 0; i < blockList.length; i++){ 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 (! requested.includes(blockList[i])){
if (blockList[i].length == 0){ if (blockList[i].length == 0){
continue continue
} }
bl = httpGet('/getblockdata/' + blockList[i])
appendMessages(bl)
requested.push(blockList[i]) 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(){ document.getElementById('refreshFeed').onclick = function(){
getBlocks() getBlocks()
} }
@ -140,7 +208,7 @@ newPostForm.onsubmit = function(){
PNotify.success({ PNotify.success({
text: "Message queued for posting" text: "Message queued for posting"
}) })
setTimeout(function(){getBlocks()}, 3000) setTimeout(function(){getBlocks()}, 500)
}) })
return false return false
} }

View File

@ -10,6 +10,7 @@
</title> </title>
<link rel='shortcut icon' type='image/ico' href='/shared/images/favicon.ico'> <link rel='shortcut icon' type='image/ico' href='/shared/images/favicon.ico'>
<link rel='stylesheet' href='/shared/main/PNotifyBrightTheme.css'> <link rel='stylesheet' href='/shared/main/PNotifyBrightTheme.css'>
<link rel="stylesheet" href="/shared/fontawesome-free-5.10.2/css/all.min.css">
<link rel='stylesheet' href='/shared/main/bulma.min.css'> <link rel='stylesheet' href='/shared/main/bulma.min.css'>
<link rel="stylesheet" href='/shared/main/styles-new.css'> <link rel="stylesheet" href='/shared/main/styles-new.css'>
<link rel="stylesheet" href="theme.css"> <link rel="stylesheet" href="theme.css">
@ -54,10 +55,10 @@
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<h1 class="title"> <h1 class="title">
Circles Circles <span class="is-pulled-right">v<span id='circlesVersion'></span></span>
</h1> </h1>
<h2 class="subtitle"> <h2 class="subtitle">
Anonymous message board Anonymous message boards
</h2> </h2>
</div> </div>
</div> </div>
@ -122,6 +123,7 @@
</div> </div>
</div> </div>
<div class="content"> <div class="content">
<span id='loadingBoard'>Loading board... <i class="fas fa-yin-yang fa-spin"></i></span>
<div id='feed'> <div id='feed'>
<span id='none'>None yet, try refreshing 😃</span> <span id='none'>None yet, try refreshing 😃</span>
<!--Message Items are appended here based on template--> <!--Message Items are appended here based on template-->

View File

@ -0,0 +1 @@
simplenotifications==0.2.18

View File

@ -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

View File

@ -10,4 +10,3 @@ unpaddedbase32==0.1.0
streamedrequests==1.0.0 streamedrequests==1.0.0
jinja2==2.10.1 jinja2==2.10.1
toomanyobjs==1.1.0 toomanyobjs==1.1.0
simplenotifications==0.2.18