// 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_timeline_event(damus, view, ev) { let max_depth = 3 if (ev.refs && ev.refs.root && view.expanded.has(ev.refs.root)) max_depth = null return render_event(damus, view, ev, {max_depth}) } function render_events(damus, view) { return view.events .filter((ev, i) => i < 140) .map((ev) => render_timeline_event(damus, view, ev)).join("\n") } function render_reply_line_top(has_top_line) { const classes = has_top_line ? "" : "invisible" return `
` } function render_reply_line_bot() { return `
` } function render_thread_collapsed(model, reply_ev, opts) { if (opts.is_composing) return "" return `
More messages in thread available. Click to expand.
` } function render_replied_events(damus, view, ev, opts) { if (!(ev.refs && ev.refs.reply)) return "" const reply_ev = damus.all_events[ev.refs.reply] if (!reply_ev) return "" opts.replies = opts.replies == null ? 1 : opts.replies + 1 const expanded = view.expanded.has(reply_ev.id) if (!expanded && !(opts.max_depth == null || opts.replies < opts.max_depth)) return render_thread_collapsed(damus, reply_ev, opts) opts.is_reply = true return render_event(damus, view, reply_ev, opts) } function render_replying_to_chat(damus, ev) { const chatroom = (ev.refs.root && damus.chatrooms[ev.refs.root]) || {} const roomname = chatroom.name || ev.refs.root || "??" const pks = ev.refs.pubkeys || [] const names = pks.map(pk => render_mentioned_name(pk, damus.profiles[pk])).join(", ") const to_users = pks.length === 0 ? "" : ` to ${names}` return `
replying${to_users} in ${roomname}
` } function render_replying_to(model, ev) { if (!(ev.refs && ev.refs.reply)) return "" if (ev.kind === 42) return render_replying_to_chat(model, ev) let pubkeys = ev.refs.pubkeys || [] if (pubkeys.length === 0 && ev.refs.reply) { const replying_to = model.all_events[ev.refs.reply] if (!replying_to) return `
reply to ${ev.refs.reply}
` pubkeys = [replying_to.pubkey] } const names = ev.refs.pubkeys.map(pk => render_mentioned_name(pk, model.profiles[pk])).join(", ") return ` replying to ${names} ` } function render_unknown_event(damus, ev) { return "Unknown event " + ev.kind } function render_boost(damus, view, ev, opts) { //todo validate content if (!ev.json_content) return "" //const profile = model.profiles[ev.pubkey] opts.boosted = { pubkey: ev.pubkey, profile: damus.profiles[ev.pubkey] } return render_event(damus, view, ev.json_content, opts) } function render_comment_body(damus, ev, opts) { const can_delete = damus.pubkey === ev.pubkey; const bar = !can_reply(ev) || opts.nobar? "" : render_action_bar(damus, ev, can_delete) const show_media = !opts.is_composing return `
${render_replying_to(damus, ev)} ${render_boosted_by(ev, opts)}

${format_content(ev, show_media)}

${render_reactions(damus, ev)} ${bar} ` } function render_boosted_by(ev, opts) { const b = opts.boosted if (!b) { return "" } // TODO encapsulate username as link/button! return `
Shared by ${render_name_plain(b.pubkey, b.profile)}
` } function render_deleted_comment_body(ev, deleted) { if (deleted.content) { return `
This content was deleted with reason:
${format_content(deleted, false)}
` } return `
This content was deleted.
` } function render_event(damus, view, ev, opts={}) { if (ev.kind === 6) return render_boost(damus, view, ev, opts) if (shouldnt_render_event(damus.pubkey, view, ev, opts)) return "" view.rendered.add(ev.id) const profile = damus.profiles[ev.pubkey] const delta = time_delta(new Date().getTime(), ev.created_at*1000) const has_bot_line = opts.is_reply const reply_line_bot = (has_bot_line && render_reply_line_bot()) || "" const deleted = is_deleted(damus, ev.id) if (deleted && !opts.is_reply) return "" const replied_events = render_replied_events(damus, view, ev, opts) let name = "" if (!deleted) { name = render_name_plain(ev.pubkey, profile) } const has_top_line = replied_events !== "" const border_bottom = opts.is_composing || has_bot_line ? "" : "bottom-border"; return ` ${replied_events}
${render_reply_line_top(has_top_line)} ${deleted ? render_deleted_pfp() : render_pfp(ev.pubkey, profile)} ${reply_line_bot}
${name} ${delta}
${deleted ? render_deleted_comment_body(ev, deleted) : render_comment_body(damus, ev, opts)}
` } function render_react_onclick(our_pubkey, reacting_to, emoji, reactions) { const reaction = reactions[our_pubkey] if (!reaction) { return `onclick="send_reply('${emoji}', '${reacting_to}')"` } else { return `onclick="delete_post('${reaction.id}')"` } } function render_reaction_group(model, emoji, reactions, reacting_to) { const pfps = Object.keys(reactions).map((pk) => render_reaction(model, reactions[pk])) let onclick = render_react_onclick(model.pubkey, reacting_to.id, emoji, reactions) return ` ${emoji} ${pfps.join("\n")} ` } function render_reaction(model, reaction) { const profile = model.profiles[reaction.pubkey] let emoji = reaction.content[0] if (reaction.content === "+" || reaction.content === "") emoji = "❤️" return render_pfp(reaction.pubkey, profile) } function render_action_bar(damus, ev, can_delete) { let delete_html = "" if (can_delete) delete_html = `