commit 6ce3ab969959e511d3d0ace5feef2f146a189962
parent 8be1da79f530321c2d7bbb98ec6d0ba9e243f82e
Author: William Casarin <jb55@jb55.com>
Date: Thu, 27 Oct 2022 17:50:23 -0700
render replies in order
Diffstat:
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>