damus.io

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

commit 94371bcc52dd20d411455bb220a9aaa1cf52f654
parent 64d4dde5dff87d6c40dfff100b753cbff6408961
Author: William Casarin <jb55@jb55.com>
Date:   Fri,  4 Nov 2022 11:31:07 -0700

web: expand thread button

This doesn't query the full thread yet, but expands what is hidden from
the thread due to the max thread depth of 3 in the home timeline.

Diffstat:
Mwebv2/damus.css | 13+++++++------
Mwebv2/damus.js | 51++++++++++++++++++++++++++++++++++++++++++---------
Mwebv2/index.html | 4++--
3 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/webv2/damus.css b/webv2/damus.css @@ -16,6 +16,10 @@ width: 60px; } +.clickable { + cursor: pointer; +} + .line-top { width: 2px; height: 5px; @@ -74,15 +78,11 @@ textarea, input { width: 80%; } -.replying-to { +.small-txt { font-size: 0.6em; color: rgba(255,255,255,0.8); } -.can-react { - cursor: pointer; -} - .reaction-group { display: inline-flex; background-color: rgba(255,255,255,0.15); @@ -186,7 +186,8 @@ html { .thread-collapsed { - margin: auto; + margin: 0 auto 5px auto; + width: 56.3%; } .comment { diff --git a/webv2/damus.js b/webv2/damus.js @@ -40,6 +40,7 @@ function init_home_model() { notifications: 0, rendered: {}, all_events: {}, + expanded: new Set(), reactions_to: {}, events: [], profiles: {}, @@ -483,17 +484,27 @@ function render_home_view(model) { ` } +function render_home_event(model, ev) +{ + let max_depth = 3 + if (ev.refs && ev.refs.root && model.expanded.has(ev.refs.root)) { + max_depth = null + } + + return render_event(model, ev, {max_depth}) +} + function render_events(model) { return model.events .filter((ev, i) => i < 140) - .map((ev) => render_event(model, ev, {max_depth: 3})).join("\n") + .map((ev) => render_home_event(model, ev)).join("\n") } function determine_event_refs_positionally(pubkeys, ids) { if (ids.length === 1) return {root: ids[0], reply: ids[0], pubkeys} - else if (ids.length === 2) + else if (ids.length >= 2) return {root: ids[0], reply: ids[1], pubkeys} return {pubkeys} @@ -544,6 +555,29 @@ const DEFAULT_PROFILE = { display_name: "Anonymous", } +function render_thread_collapsed(model, reply_ev) +{ + return `<div onclick="expand_thread('${reply_ev.id}')" class="thread-collapsed clickable">...</div>` +} + +function* yield_etags(tags) +{ + for (const tag of tags) { + if (tag.length >= 2 && tag[0] === "e") + yield tag + } +} + +function expand_thread(id) { + const ev = DSTATE.all_events[id] + if (ev) { + for (const tag of yield_etags(ev.tags)) + DSTATE.expanded.add(tag[1]) + } + DSTATE.expanded.add(id) + redraw_events(DSTATE) +} + function render_replied_events(model, ev, opts) { if (!(ev.refs && ev.refs.reply)) @@ -553,10 +587,9 @@ function render_replied_events(model, ev, opts) if (!reply_ev) return "" - opts.replies = opts.replies == null ? 1 : opts.replies + 1 if (!(opts.max_depth == null || opts.replies < opts.max_depth)) - return "" + return render_thread_collapsed(model, reply_ev, opts) opts.is_reply = true return render_event(model, reply_ev, opts) @@ -567,7 +600,7 @@ function render_replying_to_chat(model, ev) { const pks = ev.refs.pubkeys || [] const names = pks.map(pk => render_mentioned_name(pk, model.profiles[pk])).join(", ") const to_users = pks.length === 0 ? "" : ` to ${names}` - return `<div class="replying-to">replying${to_users} in ${roomid} chatroom</div>` + return `<div class="replying-to small-txt">replying${to_users} in ${roomid} chatroom</div>` } function render_replying_to(model, ev) { @@ -581,7 +614,7 @@ function render_replying_to(model, ev) { if (pubkeys.length === 0 && ev.refs.reply) { const replying_to = model.all_events[ev.refs.reply] if (!replying_to) - return `<div class="replying-to">reply to ${ev.refs.reply}</div>` + return `<div class="replying-to small-txt">reply to ${ev.refs.reply}</div>` pubkeys = [replying_to.pubkey] } @@ -589,14 +622,14 @@ function render_replying_to(model, ev) { const names = ev.refs.pubkeys.map(pk => render_mentioned_name(pk, model.profiles[pk])).join(", ") return ` - <div class="replying-to"> + <div class="replying-to small-txt"> replying to ${names} </div> ` } function render_event(model, ev, opts={}) { - if (!opts.is_composing && model.rendered[ev.id]) + if (!opts.is_composing && !model.expanded.has(ev.id) && model.rendered[ev.id]) return "" model.rendered[ev.id] = true const profile = model.profiles[ev.pubkey] || DEFAULT_PROFILE @@ -665,7 +698,7 @@ function render_reaction_group(model, emoji, reactions, reacting_to) { let classes = "" if (!reactions[model.pubkey]) { onclick = `onclick="send_reply('${emoji}', '${reacting_to.id}')"` - classes = "can-react" + classes = "clickable" } return ` diff --git a/webv2/index.html b/webv2/index.html @@ -6,7 +6,7 @@ <title>Damus</title> - <link rel="stylesheet" href="damus.css?v=10"> + <link rel="stylesheet" href="damus.css?v=11"> </head> <body> <section class="header"> @@ -41,7 +41,7 @@ <script src="noble-secp256k1.js?v=1"></script> <script src="bech32.js?v=1"></script> <script src="nostr.js?v=6"></script> - <script src="damus.js?v=41"></script> + <script src="damus.js?v=43"></script> <script> // I have to delay loading to wait for nos2x const relay = setTimeout(damus_web_init, 100)