// This file contains all methods related to rendering UI elements. Rendering // is done by simple string manipulations & templates. If you need to write // loops simply write it in code and return strings. function render_replying_to(model, ev) { if (!(ev.refs && ev.refs.reply)) return ""; let pubkeys = ev.refs.pubkeys || [] if (pubkeys.length === 0 && ev.refs.reply) { const replying_to = model.all_events[ev.refs.reply] // If there is no profile being replied to, it is simply a reply to an // event itself, thus render it differently. if (!replying_to) { return html`
`; } else { pubkeys = [replying_to.pubkey]; } } const names = pubkeys.map((pk) => { return render_name(pk, model_get_profile(model, pk).data); }).join(", ") return ` ` } function render_share(model, ev, opts) { const shared_ev = model.all_events[ev.refs && ev.refs.root] // If the shared event hasn't been resolved or leads to a circular event // kind we will skip out on it. if (!shared_ev || shared_ev.kind == KIND_SHARE) return ""; opts.shared = { pubkey: ev.pubkey, profile: model_get_profile(model, ev.pubkey), share_time: ev.created_at, share_evid: ev.id, } return render_event(model, shared_ev, opts) } function render_shared_by(ev, opts) { if (!opts.shared) return ""; const { profile, pubkey } = opts.shared return ` ` } function render_event(model, ev, opts={}) { if (ev.kind == KIND_SHARE) { return render_share(model, ev, opts); } const profile = model_get_profile(model, ev.pubkey); const delta = fmt_since_str(new Date().getTime(), ev.created_at*1000) const border_bottom = opts.is_composing ? "" : "bottom-border"; let thread_btn = ""; return html`${format_content(ev, show_media)}
`; str += render_reactions(model, ev); str += opts.nobar ? "" : render_action_bar(model, ev, {can_delete, shared}); return str; } function render_react_onclick(our_pubkey, reacting_to, emoji, reactions) { const reaction = reactions[our_pubkey] if (!reaction) { return html`onclick="send_reply('${emoji}', '${reacting_to}')"` } else { return html`onclick="delete_post('${reaction.id}')"` } } function render_reaction_group(model, emoji, reactions, reacting_to) { let count = 0; let str = ""; for (const k in reactions) { count++; if (count > 5) continue; const pubkey = reactions[k].pubkey; str += render_pfp(pubkey, model_get_profile(model, pubkey).data, {noclick:true}); } if (count > 5) str = `${count}`; let onclick = render_react_onclick(model.pubkey, reacting_to.id, emoji, reactions); return html` ${emoji} $${str} `; } function render_action_bar(model, ev, opts={}) { const { pubkey } = model; let { can_delete, shared } = opts; // TODO rewrite all of the toggle heart code. It's mine & I hate it. const thread_root = (ev.refs && ev.refs.root) || ev.id; const reaction = model_get_reacts_to(model, pubkey, ev.id, R_HEART); const liked = !!reaction; const reaction_id = reaction ? reaction.id : ""; let str = html` "; } function render_reactions_inner(model, ev) { const groups = get_reactions(model, ev.id) let str = "" for (const emoji of Object.keys(groups)) { str += render_reaction_group(model, emoji, groups[emoji], ev) } return str; } function render_reactions(model, ev) { return html`