diff --git a/contrib/static/nntpchan.js b/contrib/static/nntpchan.js index 5137920..b708ea8 100644 --- a/contrib/static/nntpchan.js +++ b/contrib/static/nntpchan.js @@ -4,8 +4,7 @@ // insert a backlink for a post given its short hash -function nntpchan_backlink(shorthash) -{ +function nntpchan_backlink(shorthash) { var elem = document.getElementById("postform_message"); if ( elem ) { @@ -13,18 +12,6 @@ function nntpchan_backlink(shorthash) } } -var banner_count = 3; - -// inject a banner into an element -function nntpchan_inject_banners(elem, prefix) { - var n = Math.floor(Math.random() * banner_count); - var banner = prefix + "static/banner_"+n+".jpg"; - var e = document.createElement("img"); - e.src = banner; - e.id = "nntpchan_banner"; - elem.appendChild(e); -} - function get_storage() { var st = null; if (window.localStorage) { @@ -47,10 +34,182 @@ function enable_theme(prefix, name) { } } -function main() { - // do other initialization here + +// call an api method +// handler(json_object) on success +// handler(null) on fail +function nntpchan_apicall(url, handler, err_handler) { + var ajax = new XMLHttpRequest(); + ajax.onreadystatechange = function() { + if (ajax.readyState == XMLHttpRequest.DONE ) { + var status = ajax.status; + var j = null; + if (status == 200) { + // found + try { + j = JSON.parse(ajax.responseText); + } catch (e) {} // ignore parse error + } else if (status == 410) { + if (err_handler) {err_handler("cannot fetch post: api disabled");} + return; + } + handler(j); + } + }; + ajax.open("GET", url); + ajax.send(); } +// build post from json +// inject into parent +// if j is null then inject "not found" post +function nntpchan_buildpost(parent, j) { + var post = document.createElement("div"); + if (j) { + // huehuehue + post.innerHTML = j.PostMarkup; + } else { + post.setAttribute("class", "notfound post"); + post.appendChild(document.createTextNode("post not found")); + } + parent.appendChild(post); +} + +// inject post hover behavior +function inject_hover(prefix, el, parent) { + if (!prefix) { throw "prefix is not defined"; } + console.log(el, parent); + var timeout; + var idx = -2; + + var linkhash = el.backlinkhash; + + var elem = document.createElement("span"); + elem.setAttribute("class", "backlink_rewritten"); + elem.appendChild(document.createTextNode(">>"+linkhash.substr(0,10))); + + parent.appendChild(elem); + parent.removeChild(el); + + elem.onclick = function(ev) { + if(elem.backlink) { + nntpchan_apicall(prefix+"api/find?hash="+linkhash, function(j) { + var wrapper = document.createElement("div"); + wrapper.setAttribute("class", "hover "+linkhash); + if (j == null) { + // not found? + wrapper.appendChild(document.createTextNode("not found")); + } else { + // wrap backlink + nntpchan_buildpost(wrapper, j); + } + elem.appendChild(wrapper); + elem.backlink = false; + }, function(msg) { + var wrapper = document.createElement("div"); + wrapper.setAttribute("class", "hover "+linkhash); + wrapper.appendChild(document.createTextNode(msg)); + elem.appendChild(wrapper); + elem.backlink = false; + }); + } else { + var elems = document.getElementsByClassName(linkhash); + if (!elems) throw "bad state, no backlinks open?"; + for (var idx = 0 ; idx < elems.length; idx ++ ) { + elems[idx].parentNode.removeChild(elems[idx]); + } + elem.backlink = true; + } + }; + elem.backlink = true; +} + +function livechan_got_post(widget, j) { + // do scroll + while (widget.children.length > 20) { + // remove top element + widget.children.removeChild(widget.children[0]); + } + nntpchan_buildpost(widget, j); + // scroll to bottom + widget.scrollTop = widget.scrollHeight; +} + +// inject post form into an element +function inject_postform(prefix, parent) { + +} + +// inject livechan widget into parent +function inject_livechan_widget(prefix, parent) { + if ( "WebSocket" in window ) { + var url = "ws://"+document.location.host+prefix+"live"; + if ( document.location.protocol == "https:" ) { + url = "wss://"+document.location.host+prefix+"live"; + } + var socket = new WebSocket(url); + var progress = function(str) { + parent.innerHTML = "
livechan: "+str+"
"; + }; + progress("initialize"); + socket.onopen = function () { + progress("connected"); + } + socket.onmessage = function(ev) { + var j = null; + try { + j = JSON.parse(ev.data); + } catch(e) { + // ignore + } + if (j) { + console.log(j); + livechan_got_post(parent, j); + } + } + socket.onclose = function(ev) { + progress("connection closed"); + setTimeout(function(){ parent.innerHTML = ""; }, 5000); + } + } else { + parent.innerHTML = "
livechan mode requires websocket support
"; + setTimeout(function() { + parent.innerHTML = ""; + }, 5000); + } +} + +function ukko_livechan(prefix) { + var ukko = document.getElementById("ukko_threads"); + if (ukko) { + // remove children + ukko.innerHTML = ""; + inject_livechan_widget(prefix, ukko); + } +} + +var banner_count = 3; + +// inject a banner into an element +function nntpchan_inject_banners(elem, prefix) { + var n = Math.floor(Math.random() * banner_count); + var banner = prefix + "static/banner_"+n+".jpg"; + var e = document.createElement("img"); + e.src = banner; + e.id = "nntpchan_banner"; + elem.appendChild(e); +} + +function init(prefix) { + // inject posthover ... + var elems = document.getElementsByClassName("backlink"); + // ... for backlinks + for ( var idx = 0 ; idx < elems.length ; idx ++ ) { + // uncomment to do reply hover + //inject_hover(prefix, elems[idx], elems[idx].parentNode); + } +} + // apply themes var st = get_storage(); enable_theme(st.nntpchan_prefix, st.nntpchan_theme); diff --git a/contrib/static/site.css b/contrib/static/site.css index 631fb79..c570c09 100644 --- a/contrib/static/site.css +++ b/contrib/static/site.css @@ -394,7 +394,11 @@ input, textarea { } -.backlink, .backlink:hover, .backlink:visited, .backlink:visited:hover { +.backlink_rewritten { + z-index: 5; +} + +.backlink, .backlink:hover, .backlink:visited, .backlink:visited:hover, .backlink_rewritten { margin-left: none; color: #D00 } diff --git a/contrib/templates/default/board.mustache b/contrib/templates/default/board.mustache index 2be0590..acc482f 100644 --- a/contrib/templates/default/board.mustache +++ b/contrib/templates/default/board.mustache @@ -20,7 +20,7 @@ {{board.Board}} - + {{{board.Navbar}}} @@ -55,10 +55,10 @@ {{#i18n.Translations}}{{catalog_label}}{{/i18n.Translations}}