damus.io

damus.io website
git clone git://jb55.com/damus.io
Log | Files | Refs | README

commit 6ce3ab969959e511d3d0ace5feef2f146a189962
parent 8be1da79f530321c2d7bbb98ec6d0ba9e243f82e
Author: William Casarin <jb55@jb55.com>
Date:   Thu, 27 Oct 2022 17:50:23 -0700

render replies in order

Diffstat:
Mwebv2/Makefile | 2+-
Mwebv2/damus.css | 19++++++++++++++++++-
Mwebv2/damus.js | 91++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Mwebv2/index.html | 2+-
4 files changed, 106 insertions(+), 8 deletions(-)

diff --git a/webv2/Makefile b/webv2/Makefile @@ -6,6 +6,6 @@ tags: fake ctags damus.js nostr.js > $@ dist: - rsync -avzP ./ charon:/www/damus.io/web/ + rsync -avzP ./ charon:/www/damus.io/webv2/ .PHONY: fake diff --git a/webv2/damus.css b/webv2/damus.css @@ -15,6 +15,23 @@ width: 60px; } +.line-top { + width: 2px; + height: 5px; + background-color: #eac3ff; + margin-left: auto; + margin-right: auto; +} + +.line-bot { + width: 2px; + height: 100%; + margin-top: -7px; + background-color: #eac3ff; + margin-left: auto; + margin-right: auto; +} + body { min-height: 100vh; font-family: system-ui, sans; @@ -123,7 +140,7 @@ html { font-family: system-ui, sans; margin-bottom: 20px; flex-wrap: wrap; - align-items: center; + /*align-items: center;*/ } .comment p { diff --git a/webv2/damus.js b/webv2/damus.js @@ -37,6 +37,7 @@ function init_home_model() { return { done_init: false, loading: true, + rendered: {}, all_events: {}, events: [], profiles: {}, @@ -98,14 +99,21 @@ async function damus_web_init(thread) return pool } +function process_event(ev) +{ + ev.refs = determine_event_refs(ev.tags) +} + let rerender_home_timer function handle_home_event(ids, model, relay, sub_id, ev) { model.all_events[ev.id] = ev switch (sub_id) { case ids.home: - if (ev.content !== "") + if (ev.content !== "") { + process_event(ev) insert_event_sorted(model.events, ev) + } if (model.realtime) { if (rerender_home_timer) clearTimeout(rerender_home_timer) @@ -320,15 +328,65 @@ function handle_comments_loaded(profiles_id, model, relay) function render_home_view(model) { log_debug("rendering home view") + model.rendered = {} model.el.innerHTML = render_events(model) } function render_events(model) { - const render = render_event.bind(null, model) - return model.events.map(render).join("\n") + return model.events.map((ev) => render_event(model, ev)).join("\n") +} + +function determine_event_refs_positionally(ids) +{ + if (ids.length === 1) + return {reply: ids[0]} + else if (ids.length === 2) + return {root: ids[0], reply: ids[1]} + + return {} +} + +function determine_event_refs(tags) { + let positional_ids = [] + let root + let reply + let i = 0 + + for (const tag of tags) { + if (tag.length >= 4 && tag[0] == "e") { + if (tag[3] === "root") + root = tag[1] + else if (tag[3] === "reply") + reply = tag[1] + + // we found both a root and a reply, we're done + if (root !== undefined && reply !== undefined) + break + } else if (tag.length >= 2 && tag[0] == "e") { + positional_ids.push(tag[1]) + } + + i++ + } + + if (!root && !reply && positional_ids.length > 0) + return determine_event_refs_positionally(positional_ids) + + return {root, reply} +} + +function render_reply_line_top() { + return `<div class="line-top"></div>` +} + +function render_reply_line_bot() { + return `<div class="line-bot"></div>` } function render_event(model, ev, opts={}) { + if (model.rendered[ev.id]) + return "" + model.rendered[ev.id] = true const profile = model.profiles[ev.pubkey] || { name: "anon", display_name: "Anonymous", @@ -336,13 +394,36 @@ function render_event(model, ev, opts={}) { const delta = time_delta(new Date().getTime(), ev.created_at*1000) const pk = ev.pubkey const bar = opts.nobar? "" : render_action_bar(ev) + + let replying_to = "" + let reply_line_top = "" + + const has_bot_line = opts.is_reply + + if (ev.refs && ev.refs.reply) { + const reply_ev = model.all_events[ev.refs.reply] + if (reply_ev) { + opts.replies = opts.replies == null ? 1 : opts.replies + 1 + opts.is_reply = true + replying_to = render_event(model, reply_ev, opts) + reply_line_top = render_reply_line_top() + } + } + + const reply_line_bot = (has_bot_line && render_reply_line_bot()) || "" + return ` - <div class="comment"> + ${replying_to} + <div id="ev${ev.id}" class="comment"> <div class="info"> ${render_name(ev.pubkey, profile)} <span>${delta}</span> </div> - <img class="pfp" onerror="this.onerror=null;this.src='${robohash(pk)}';" src="${get_picture(pk, profile)}"> + <div> + ${reply_line_top} + <img class="pfp" onerror="this.onerror=null;this.src='${robohash(pk)}';" src="${get_picture(pk, profile)}"> + ${reply_line_bot} + </div> <p> ${format_content(ev.content)} diff --git a/webv2/index.html b/webv2/index.html @@ -43,7 +43,7 @@ <script src="noble-secp256k1.js?v=1"></script> <script src="bech32.js?v=1"></script> <script src="nostr.js?v=3"></script> - <script src="damus.js?v=5"></script> + <script src="damus.js?v=7"></script> <script> const relay = damus_web_init("4e8b44bb43018f79bd3efcdcd71af43814cdf996e0c62adedda1ac33bf5e1371") </script>