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.
This commit is contained in:
William Casarin 2022-11-04 11:31:07 -07:00
parent 64d4dde5df
commit 94371bcc52
3 changed files with 51 additions and 17 deletions

View file

@ -16,6 +16,10 @@
width: 60px; width: 60px;
} }
.clickable {
cursor: pointer;
}
.line-top { .line-top {
width: 2px; width: 2px;
height: 5px; height: 5px;
@ -74,15 +78,11 @@ textarea, input {
width: 80%; width: 80%;
} }
.replying-to { .small-txt {
font-size: 0.6em; font-size: 0.6em;
color: rgba(255,255,255,0.8); color: rgba(255,255,255,0.8);
} }
.can-react {
cursor: pointer;
}
.reaction-group { .reaction-group {
display: inline-flex; display: inline-flex;
background-color: rgba(255,255,255,0.15); background-color: rgba(255,255,255,0.15);
@ -186,7 +186,8 @@ html {
.thread-collapsed { .thread-collapsed {
margin: auto; margin: 0 auto 5px auto;
width: 56.3%;
} }
.comment { .comment {

View file

@ -40,6 +40,7 @@ function init_home_model() {
notifications: 0, notifications: 0,
rendered: {}, rendered: {},
all_events: {}, all_events: {},
expanded: new Set(),
reactions_to: {}, reactions_to: {},
events: [], events: [],
profiles: {}, 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) { function render_events(model) {
return model.events return model.events
.filter((ev, i) => i < 140) .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) function determine_event_refs_positionally(pubkeys, ids)
{ {
if (ids.length === 1) if (ids.length === 1)
return {root: ids[0], reply: ids[0], pubkeys} 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 {root: ids[0], reply: ids[1], pubkeys}
return {pubkeys} return {pubkeys}
@ -544,6 +555,29 @@ const DEFAULT_PROFILE = {
display_name: "Anonymous", 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) function render_replied_events(model, ev, opts)
{ {
if (!(ev.refs && ev.refs.reply)) if (!(ev.refs && ev.refs.reply))
@ -553,10 +587,9 @@ function render_replied_events(model, ev, opts)
if (!reply_ev) if (!reply_ev)
return "" return ""
opts.replies = opts.replies == null ? 1 : opts.replies + 1 opts.replies = opts.replies == null ? 1 : opts.replies + 1
if (!(opts.max_depth == null || opts.replies < opts.max_depth)) if (!(opts.max_depth == null || opts.replies < opts.max_depth))
return "" return render_thread_collapsed(model, reply_ev, opts)
opts.is_reply = true opts.is_reply = true
return render_event(model, reply_ev, opts) return render_event(model, reply_ev, opts)
@ -567,7 +600,7 @@ function render_replying_to_chat(model, ev) {
const pks = ev.refs.pubkeys || [] const pks = ev.refs.pubkeys || []
const names = pks.map(pk => render_mentioned_name(pk, model.profiles[pk])).join(", ") const names = pks.map(pk => render_mentioned_name(pk, model.profiles[pk])).join(", ")
const to_users = pks.length === 0 ? "" : ` to ${names}` 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) { function render_replying_to(model, ev) {
@ -581,7 +614,7 @@ function render_replying_to(model, ev) {
if (pubkeys.length === 0 && ev.refs.reply) { if (pubkeys.length === 0 && ev.refs.reply) {
const replying_to = model.all_events[ev.refs.reply] const replying_to = model.all_events[ev.refs.reply]
if (!replying_to) 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] 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(", ") const names = ev.refs.pubkeys.map(pk => render_mentioned_name(pk, model.profiles[pk])).join(", ")
return ` return `
<div class="replying-to"> <div class="replying-to small-txt">
replying to ${names} replying to ${names}
</div> </div>
` `
} }
function render_event(model, ev, opts={}) { 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 "" return ""
model.rendered[ev.id] = true model.rendered[ev.id] = true
const profile = model.profiles[ev.pubkey] || DEFAULT_PROFILE const profile = model.profiles[ev.pubkey] || DEFAULT_PROFILE
@ -665,7 +698,7 @@ function render_reaction_group(model, emoji, reactions, reacting_to) {
let classes = "" let classes = ""
if (!reactions[model.pubkey]) { if (!reactions[model.pubkey]) {
onclick = `onclick="send_reply('${emoji}', '${reacting_to.id}')"` onclick = `onclick="send_reply('${emoji}', '${reacting_to.id}')"`
classes = "can-react" classes = "clickable"
} }
return ` return `

View file

@ -6,7 +6,7 @@
<title>Damus</title> <title>Damus</title>
<link rel="stylesheet" href="damus.css?v=10"> <link rel="stylesheet" href="damus.css?v=11">
</head> </head>
<body> <body>
<section class="header"> <section class="header">
@ -41,7 +41,7 @@
<script src="noble-secp256k1.js?v=1"></script> <script src="noble-secp256k1.js?v=1"></script>
<script src="bech32.js?v=1"></script> <script src="bech32.js?v=1"></script>
<script src="nostr.js?v=6"></script> <script src="nostr.js?v=6"></script>
<script src="damus.js?v=41"></script> <script src="damus.js?v=43"></script>
<script> <script>
// I have to delay loading to wait for nos2x // I have to delay loading to wait for nos2x
const relay = setTimeout(damus_web_init, 100) const relay = setTimeout(damus_web_init, 100)